正则表达式

1,389 阅读3分钟

正则表达式

正则表达式的模糊匹配

正则表达式有两种模糊匹配方式:横向模糊匹配和纵向模糊匹配

横向模糊匹配:
reg = /ab{2,5}b/;
表示`b`这个字符出现25
纵向模糊匹配:
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';
})