轉(zhuǎn)義字符
let str = '<div>a</div>\
<div>b</div>'
console.log(str); // js只允許當(dāng)行字符串来累,這里的 \ 是把后面的空格轉(zhuǎn)義
\n 換行
\r 回車
\t
正則的兩種寫法及應(yīng)用
var reg = new RegExp('abc', 'igm');
var reg = /abc/igm;
應(yīng)用:一般使用對(duì)象字面量(第二種)
let rule = 'abc';
var reg = new RegExp(rule, 'igm'); // 要使用變量的情況下就要使用第一種情況津滞,因?yàn)閷?duì)象字面量會(huì)把rule當(dāng)作一個(gè)字符串
正則修飾符/正則屬性
- i: 忽略大小寫
- g:全局匹配
- m: 多行匹配
const reg = /^test/;
const str = 'abcasfdas \ntestasdasd';
console.log(reg.test(str)); // false
const reg2 = /^test/m;
console.log(reg2.test(str)); // true
方括號(hào)[] 參考: https://www.w3school.com.cn/jsref/jsref_obj_regexp.asp
[abc]: 取abc中的任意一個(gè)
[^abc]: 取非abc的任意一個(gè)钮莲, ^ 在 [] 是 非 的意思
/abc|123/g: 取 abc 或者 123
練習(xí):我們要匹配 abc 或者 123 后再跟一位字母 q
/abc|123q/g //這樣寫是錯(cuò)誤的咏花,會(huì)匹配為 abc 或者 23q
/(abc|123)q/ // ()會(huì)提升優(yōu)先級(jí)婆廊,先執(zhí)行()里面的
量詞 參考: https://www.w3school.com.cn/jsref/jsref_obj_regexp.asp
參考文檔很詳細(xì)串纺,這里不多描述俭茧,只講一些注意點(diǎn)
var str = "abcd";
var reg = /\w+/g;
var reg = /\w*/g;
console.log(str.match(reg)); // ["abcd"]
console.log(str.match(reg2)); // ["abcd", ""] *是0到多次,匹配到 abcd 后锡足,還會(huì)匹配一次 ""
練習(xí)
var str = "abcd";
var reg = /\d*/g;
console.log(str.match(reg)); // ["", "", "", "", ""]
var str = "abcd";
var reg = /\w?/g;
console.log(str.match(reg)); // ["a", "b", "c", "d", ""]
子表達(dá)式,反向引用 (\n) ()除了提升權(quán)重外蹬敲,還表示子表達(dá)式
let str = 'aabbbbaaaabbbbwxxxxiaaaa';
let reg = /(a)(b)\2\2\2/g; // \n的n并不是數(shù)量暇昂,而是第幾個(gè)引用,這里\1引用的就是a,\2引用就是b
console.log(str.match(reg));
let reg2 = /(\w)\1\1\1/g; // 這樣可以匹配到所有 aaaa bbbb cccc 這種格式
console.log(str.match(reg2));
let reg3 = /(\w)\1(\w)\2/g; // 這樣可以匹配到所有 aaaa bbbb cccc 這種格式
console.log(str.match(reg3)); // 匹配 aabb xxyy 這種格式
貪婪模式和非貪婪模式
{
let str = "abc{{name}}safds{{age}}";
let reg = /{{(.*)}}/g;
console.log(reg.exec(str)); // "{{name}}safds{{age}}" 貪婪匹配伴嗡,
let reg2 = /{{(.*?)}}/g;
console.log(str.match(reg2)); // ["{{name}}", "{{age}}"] ?表示0或一次急波,但是在一些不是具體的量詞(如+?*)后面表示 非貪婪匹配瘪校,能少匹配就不會(huì)多匹配
}
{
let str = 'abcds';
let reg = /\w??/g;
console.log(str.match(reg)); // ["", "", "", "", "", ""]
}
屬性
- global:正則是否設(shè)置了全局匹配澄暮,return Boolean
- ignoreCase
- multiline]
- source : 返回正則的匹配規(guī)則
- lastIndex:一個(gè)整數(shù),標(biāo)示開始下一次匹配的字符位置阱扬。(與exec中結(jié)合講解)
方法
- test() return Boolean
- exec()
全局匹配的情況下
let str = 'ababab';
let reg = /ab/g;
console.log(reg.lastIndex); // 0
console.log(reg.exec(str)); // ["ab", index: 0, input: "ababab", groups: undefined]
console.log(reg.lastIndex); // 2
console.log(reg.exec(str)); // ["ab", index: 2, input: "ababab", groups: undefined]
console.log(reg.lastIndex); // 4
console.log(reg.exec(str)); // ["ab", index: 4, input: "ababab", groups: undefined]
console.log(reg.lastIndex); // 6 // 這里是6的原因是開始下一次匹配的字符位置
console.log(reg.exec(str)); // null
console.log(reg.lastIndex); // 0
console.log(reg.exec(str)); // ["ab", index: 0, input: "ababab", groups: undefined]
// 可以發(fā)現(xiàn) reg.lastIndex 標(biāo)示開始下一次匹配的字符位置泣懊,和 exec() 匹配結(jié)果中的 index 幾乎一樣
// 而 reg.lastIndex 屬性是可以修改的,我們修改一下試試
console.log('-----------------------');
reg.lastIndex = 4;
console.log(reg.lastIndex);
console.log(reg.exec(str)); // 可以發(fā)現(xiàn) reg.lastIndex 的修改會(huì)影響 exec 的匹配結(jié)果麻惶,exec會(huì)從reg.lastIndex處開始匹配
// 如果我們修改一個(gè)不剛好匹配的值呢
console.log('+++++++++++++++++++++++++');
reg.lastIndex = 1;
console.log(reg.lastIndex); // 1
console.log(reg.exec(str)); // ["ab", index: 2, input: "ababab", groups: undefined]
console.log(reg.lastIndex); // 4
console.log(reg.exec(str)); // ["ab", index: 4, input: "ababab", groups: undefined]
// reg.lastIndex 會(huì)根據(jù) exec 的匹配結(jié)果進(jìn)行修正
{
let str = "aabbccaadd";
let reg = /(\w)\1(\w)\2/g;
console.log(reg.exec(str)); // ["aabb", "a", "b", index: 0, input: "aabbccaadd", groups: undefined]
// aabb就是匹配到的字符串馍刮, 'a' 'b' 就是子表達(dá)式, index解釋過窃蹋,input就是str
}
非全局匹配:匹配的永遠(yuǎn)是第一個(gè)卡啰,且修改lastIndex無效
{
let str = "abc";
let reg = /\w/;
console.log(reg.exec(str));
console.log(reg.exec(str));
reg.lastIndex = 2;
console.log(reg.exec(str));
}
支持正則表達(dá)式的 String 對(duì)象的方法
- match
區(qū)別:
match
- 加 g ,返回一個(gè)類數(shù)組警没,數(shù)組中的每一項(xiàng)是匹配的值
- 不加 g匈辱,匹配的和 exec 一置,永遠(yuǎn)返回第一個(gè)匹配的結(jié)果杀迹,且修改reg.lastIndex不會(huì)對(duì)其匹配照成影響
exec
- 加 g亡脸,執(zhí)行一次匹配一次,與lastIndex相互影響
- 不加 g,和match一致
- split
- replace
{
let str = 'jsplusplus';
let res = str.replace('plus', '+'); // replace(regexp/substr,replacement) param1: 被替換的梗掰, param2:替換后的
console.log(res); // js+plus replace并沒用全局匹配的能力 相當(dāng)于 str.replace(/plus/, '+');
}
{
let str = "aabbccdd"; // 替換為 bbaaddcc
let reg = /(\w)\1(\w)\2/g;
let res = str.replace(reg, '$2$2$1$1'); // $1就是子表達(dá)式\1的那個(gè)值嵌言, 這里的reg匹配到str有 aabb ccdd 將aabb替換為bbaa, ccdd替換為ddcc
console.log(res);
// 方式二
str.replace(reg, ($, $1, $2) => {
console.log($, $1, $2); // aabb a b ccdd c d $:匹配的字符串 $1,$2:子表達(dá)式的值
return $2 + $2 + $1 + $1;
});
}
{
// 練習(xí)
let str = "js-plus-plus"; // 變?yōu)?jsPlusPlus
let reg = /-(\w)/g; // 這里的$1匹配的是子表達(dá)式及穗,必須要加()
let res = str.replace(reg, ($, $1) => {
return $1.toUpperCase();
});
console.log(res);
}
{
// 練習(xí)
let str = "jsPlusPlus"; // 變?yōu)?js-plus-plus
let reg = /(P)/g;
let res = str.replace(reg, ($, $1) => {
return '-' +$1.toLowerCase();
});
console.log(res);
}
{
// 練習(xí) xxyyzz => XxYyZz
let str = "xxyyzz";
let reg = /(\w)\1/g;
let res = str.replace(reg, ($, $1) => {
return $1.toUpperCase() + $1;
});
console.log(res);
}
{
// 練習(xí) aabbcc => a$b$c$,不使用function方式
let str = "aabbcc";
let reg = /(\w)\1(\w)\2(\w)\3/g;
let res = str.replace(reg, '$1$$$2$$$3$$'); // 要使用$,必須寫兩個(gè)$,因?yàn)?有特殊含義
console.log(res);
}