正则表达式
正则表达式的模糊匹配
正则表达式有两种模糊匹配方式:横向模糊匹配和纵向模糊匹配
横向模糊匹配:
reg = /ab{2,5}b/;
表示`b`这个字符出现2到5次
纵向模糊匹配:
reg = /a[123]b/;
表示要匹配的字符串只能是:`a1b`,`a2b`,`a3b`
正则表达式的排除字符组
排除字符组
[^abc];
表示除`a`,`b`,`c`以外的任意字符
量词(也称重复)
| 量词 | 含义 |
|---|---|
| {m,} | 表示至少出现m次 |
| {m} | 表示出现m次 |
| ? | 等价与 {0,1}, 表示出现或者不出现 |
| + | 等价于 {1,}, 表示至少出现1次 |
| * | 等价于 {0,}, 表示出现任意次,有可能不出现 |
贪婪匹配和惰性匹配
例如: /\d{2,5}/g 会匹配2-5个数字字符,
/\d{2,5}?/g 则匹配到2个数字字符就会停止匹配
对惰性匹配的记忆方式是:量词后面加个问号
?
正向先行断言和负向先行断言
(?=p): 意思是p前面的那个位置;
(?!p): 意思是紧跟的后面不包括P;
把位置理解空字符,是对位置非常有效的理解方式。
不匹配任何东西的正则;
/.^/: 不会匹配任何东西;
数字的千位分隔符表示法
let res = '123456789'.replace(/(?!^)(?=(\d{3})+$)/g, ",");
输出: 123,456,789
let res = '123456789 123465789'.replace(/\B(?=(\d{3})+\b)/g, ",")
输出:"123,456,789 123,465,789"
格式化货币
let res = num.toFixed(2).replace(/\B(?=(\d{3})+\b)/g, ",").replace(/^/, "$$ ")
输出:"$ 1,888.00"
反向引用
> 有如下正则: /\d{4}(-|\/|.)\d{2}(-|\/|.)\d${2}/;
> 我们想匹配2021-08-30 2021.08.30 2021/08/30
> 但是也能匹配到2021-08/30这样的,想要前后一致就需要用到反向引用, 修改正则如下
/\d{4}(-|\/|.)\d{2}\1\d${2}/
非捕获括号
正则表达式中的括号,通常会捕获它们匹配到的数据,以便后续引用,因此也称为捕获型分组。
如果只想使用括号最原始的功能,但不会引用它,此时可以使用非捕获括号
(?:p) 和 (?:p1|p2|p3);
正则表达式的回溯
- 使用的是深度优先搜索;
- 简单总结就是,正因为有多种可能,所以要一个一个试,直到,要么到某一步,整体匹配成功了,要么最后都试完了,发现整体匹配不成功;
- 贪婪量词“试”的策略是:买衣服砍价。价钱太高了,便宜点,不行,再便宜点
- 惰性量词“试”的策略是:卖东西加价。给少了,再多给点行不,还有点少啊,再给点
- 分支结构“试”的策略是:货比三家。这家不行,换一家吧,还不行,再换。
身份证正则表达式
/^(\d{15}|\d{17}[\dxX])$/
密码正则,大小写包含数字,不能出现连续的数字和相同的数字5次
const PassWrodRegOne = /^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z\S]{8,20}$/;
const PassWrodRegTwo = /(0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){4}\d/g;
const PassWrodRegThree = /(\d)\1{4}/g;
一般不推荐使用构造函数生成正则,应该优先使用字面量,因为用构造函数会多谢很多\
var string = "2017-06-27 2017.06.27 2017/06/27";
var regex = /\d{4}(-|\.|\/)\d{2}\1\d{2}/g;
console.log( string.match(regex) );
// => ["2017-06-27", "2017.06.27", "2017/06/27"]
regex = new RegExp("\\d{4}(-|\\.|\\/)\\d{2}\\1\\d{2}", "g");
console.log( string.match(regex) );
// => ["2017-06-27", "2017.06.27", "2017/06/27"]
优先使用字面量来创建正则,但有时候正则表达式的主体是不确定的,此时可以使用构造函数来创建
使用构造函数生成正则表达式
function getElementsByClassName(className) {
var elememts = document.getElementsByTagName("*");
var regex = new RegExp("(^|\\s)" + className + "(\\s|$)");
var res = [];
for(var i = 0; i < elememts.length; i++) {
var element = elememts[i];
if (regex.test(elememts.className)) {
res.push(element);
}
}
return res;
}
var highs = getElementsByClassName('high');
highs.forEach(item => {
item.style.color = 'red';
})