别百度正则了,一篇正则详解带你搞懂正则

Posted 小小码农,可笑可笑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了别百度正则了,一篇正则详解带你搞懂正则相关的知识,希望对你有一定的参考价值。

目录

语法模式

元字符列表:( [ { \\ ^ $ | ) ] } ? * + .

标记(flags)

实例RegExp常用方法exec()和test()

exec()

test()

元字符示例:

捕获括号() 

中括号[]

大括号{}

反斜杠 \\   

它叫啥 ^

或 | 

问号?,星号*,加号+

小数点 .

常用正则


语法模式

let expression = /pattern/flags

其实正则还是要了解每一个规则是什么意思,用代码走一遍就好了。

 

元字符列表:( [ { \\ ^ $ | ) ] } ? * + .

元字符含义
()它会匹配 字符串 并且记住匹配项。其中括号被称为捕获括号
[]一个字符集合
{}出现次数
\\

非特殊字符之前的反斜杠表示下一个字符是特殊字符

特殊字符之前的反斜杠表示下一个字符不是特殊字符(转义)

^匹配输入字行首;或一个反向字符集
$匹配输入的结束。如果多行标志被设置为 true,那么也匹配换行符前的位置
|
?匹配前面一个表达式 0 次或者 1 次。等价于 {0,1}
*匹配前一个表达式 0 次或多次。等价于 {0,}
+匹配前面一个表达式 1 次或者多次。等价于 {1,}
.默认匹配除换行符之外的任何单个字符。
特殊字符含义
(?:x)非捕获括号,匹配x但不记住匹配项
x(?=y)匹配后面跟着字y的x
(?<=y)x匹配前面跟着字y的x
x(?!y)匹配后面不跟着y的x
 (以下大写字母为其反集,就不叙述)
\\b匹配字边界
\\d匹配一个数字,等价于[0-9]
\\s匹配一个空白字符,包括空格、制表符、换页符和换行符
\\w匹配一个单字字符(字母、数字或者下划线)。等价于 [A-Za-z0-9_]

标记(flags)

  • g:全局模式。表示查找字符串的全部内容。
  • i:不区分大小写。表示在查找匹配时忽略pattern 和字符串的大小写。
  • m:多行模式。表示查找到一行文本的末尾时会继续查找。
  • y:粘贴模式。表示只查找从lastIndex开始及之后的字符串。
  • u:Unicode模式。启用Unicode匹配。
  • s:doAll模式。表示元字符.匹配任何字符。(包括\\n或\\r)

展开示例前我们先说下javascript中正则实例RegExp,其包含两个常用方法exec()和test()

实例RegExp常用方法exec()和test()

exec()

包含一个参数,也就是你要正则的字符串。具体函数的意义比较抽象。红宝书上说用于捕获组使用。抽象吧?所以还是代码跑起来,看看它到底干了啥

let re = new RegExp('i','g');
let str = 'hii_;';
console.log('exec()返回对象:',re.exec(str));

这里的0代表了匹配的字符串。goups不做叙述,因为我也不知道。index代表匹配字符的位置,input代表匹配的完整字符串。接下来就是exec的机制问题,类似于next,继续上代码

let re = new RegExp('i','g');
let str = 'hii_;';
for(let i=0; i<10; i++){
    console.log('exec()返回对象:',re.exec(str));
}

迭代返回匹配的字符串,直到找不到后,继续迭代。

刚刚我们是全局模式,如果不是全局模式呢?

let re = new RegExp('i');
let str = 'hii_;';
for(let i=0; i<10; i++){
    console.log('exec()返回对象:',re.exec(str));
}

可以清晰地看到,仅返回第一个匹配项。如果没有标记,exec仅返回第一个匹配项 

还有粘贴模式,也就是标记y,也是特殊的,它只会在lastIndex的位置上寻找。

let re = new RegExp('i','y');
let str1 = 'ii';
let str2 = 'hi';
console.log('lastIndex',re.lastIndex);
console.log('str2:',re.exec(str2));
console.log('lastIndex',re.lastIndex);
console.log('str1:',re.exec(str1));
console.log('lastIndex',re.lastIndex);
console.log('again - str2:',re.exec(str2));

通过打印,我们可以看到开始时lastIndex=0,所以从第0位开始匹配,因此str2没有匹配到;因此lastIndex没有变化,继续从0开始匹配str1,匹配到了,lastIndex变为1;继续匹配str2,则在第1位匹配到。这个例子不仅能理解什么是y模式,也可以理解当标记是y时的exec函数是如何执行的。

test()

test()函数,判断字符串是否与规定模式相匹配,比较基本,不多说了。

let re1 = new RegExp('i','y');
let re2 = new RegExp('i','g');
let str1 = 'hi';
console.log(re1.test(str1));//false
console.log(re2.test(str1));//true

元字符示例:

  • 捕获括号() 

这个字符,mdn解释的也很抽象。我们看几个例子就明白了

let re1 = new RegExp('(i)','g');
let re2 = new RegExp('i','g');
let re3 = new RegExp('(i)\\\\1','g');
let str1 = 'hiiiiiikikikkk';
console.log('只有捕获括号:',re1.exec(str1));
console.log('捕获括号和组里值复用:',re3.exec(str1));
console.log('基本:',re2.exec(str1));
console.log('re1+str1_2:',re2.exec(str1));

 

这个()叫捕获括号,非捕获括号后面有机会再说。我们可以看到打印,带()的比基本的多了一个1:"i",这就是定义所说的记住匹配项,最多记住9个,通过/1-9来表示(里面的\\\\是将\\转义了),所以(i)\\\\1所代表的就是匹配ii。

  • 中括号[]

这个就简单了,就是一个字符集,依旧上例子

let re1 = new RegExp('[hi]','g');
let str1 = 'hiiiiiikikikkk';
for(let i=0;i<str1.length;i++){
  console.log('中括号'+i+':',re1.exec(str1));
}
console.log('中括号匹配测试:',re1.test(str1));

只匹配h和i

  • 大括号{}

它包含三种形式,以下m,n均为正整数。{n}出现n次,{n,}出现至少n次,{n,m}出现n-m次之间包含n,m

let re1 = new RegExp('i{2}','g');
let re2 = new RegExp('i{2,}','g');
let re3 = new RegExp('i{2,3}','g');
let str1 = 'hiiiiiikikiikkk';
for(let i=0;i<str1.length;i++){
  let result = re1.exec(str1);
  if(!result) break;
  console.log('{}re1-'+i+':',result);
}
for(let i=0;i<str1.length;i++){
  let result = re2.exec(str1);
  if(!result) break;
  console.log('{}re2-'+i+':',result);
}
for(let i=0;i<str1.length;i++){
  let result = re3.exec(str1);
  if(!result) break;
  console.log('{}re3-'+i+':',result);
}

不多说。

  • 反斜杠 \\   

这里的特殊字符包含很多,包括之前括号中所说的\\n。还有类似的数字\\d,单字字符\\w等。转义更不用多说。这就不写例子了,因为比较好理解。

  • 它叫啥 ^

这个元字符,取反向集,也很好理解,不多说。上个简单写法例子

let re = new RegExp('[^hi]','g');
let str = 'hiik';
console.log('^re:',re.exec(str));//应该只匹配k
  • $  匹配字符的结束
let re1 = new RegExp('k$','g');
let re2 = new RegExp('i$','g');
let re3 = new RegExp('k{2}$','g');
let str1 = 'hiiiiiikikiikkk';
for(let i=0;i<str1.length;i++){
  let result = re1.exec(str1);
  if(!result) break;
  console.log('$re1-'+i+':',result);
}
for(let i=0;i<str1.length;i++){
  let result = re2.exec(str1);
  if(!result) break;
  console.log('$re2-'+i+':',result);
}
for(let i=0;i<str1.length;i++){
  let result = re3.exec(str1);
  if(!result) break;
  console.log('$re3-'+i+':',result);
}

很简单,下一个

  • 或 | 

没什么说的

  • 问号?,星号*,加号+

各自等价于{}的几种常用形式,不再叙述。

  • 小数点 .

这个匹配任何字符很好理解,不过还是写个例子,因为还要理解下,匹配任何字符不代表没有,还有在前在后。

let re = new RegExp('[.hi]','g');
let re1 = new RegExp('[hi.]','g');
let str = 'hiik';
console.log('^re:',re.exec(str));//不匹配,因为str的hi前面没有任何字

console.log('^re1:',re1.exec(str));//匹配hii

其实看了以上特殊字符,后续的理解起来就不难了,如果你一边敲一边想的话,剩余的几个常用的就不列例子了,各位有兴趣可以自己敲以下。

下面送几个常用的正则匹配

常用正则

/**
 * 用户名:字母数字下划线减号
 * @param {*} str
 * @returns
 */
export function isAdminName(str){
    if(str){
        let re = new RegExp('^[\\\\w-]{4,16}$','g')
        return re.test(str)
    }else{
        console.error('请传参')
    }
}

/**
 * 密码:大于6位,至少包含1个数字、大写字母、小写字母和特殊符号
 * @param {*} str
 * @returns
 */
export function isPassword(str){
    if(str){
        let re = new RegExp('^.*(?=.{6,})(?=.*\\\\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$','g')
        return re.test(str)
    }else{
        console.error('请传参')
    }
}

/**
 * 银行密码:6位数字
 * @param {*} str
 * @returns
 */
export function isBankPassword(str){
    if(str){
        let re = new RegExp('^\\\\d{6}$','g')
        return re.test(str)
    }else{
        console.error('请传参')
    }
}

/**
 * 正整数:重复一次或者多次0-9
 * @param {*} str
 * @returns
 */
export function isPositiveInteger(str){
    if(str){
        let re = new RegExp('^\\\\d+$','g')
        return re.test(str)
    }else{
        console.error('请传参')
    }
}

/**
 * 负整数
 * @param {*} str
 * @returns
 */
export function isNegtiveInteger(str){
    if(str){
        let re = new RegExp('^-\\\\d+$','g')
        return re.test(str)
    }else{
        console.error('请传参')
    }
}

/**
 * 整数
 * @param {*} str
 * @returns
 */
export function isInteger(str){
    if(str){
        let re = new RegExp('^-?\\\\d+$','g')
        return re.test(str)
    }else{
        console.error('请传参')
    }
}

/**
 * 手机号:所有号码号段详见百度百科手机号码
 * @param {*} str
 * @returns
 */
export function isMobilePhone(str){
    if(str){
        let re = new RegExp('^(((13[0-9])|(14[0-1|4-9])|(15([0-3]|[5-9]))'+
        '(16[2|5-7])|(17[1-8])|(18[0-9])|(19[0-3|5-9]))\\\\d{8}$)|([1700-1709]|1349)\\\\d{7}$)','g')
        return re.test(str)
    }else{
        console.error('请传参')
    }
}

/**
 * 身份证号:有关身份证号具体规则详见百度百科身份证号码
 * @param {*} str
 * @returns
 */
export function isIDNum(str){
    if(str){
        let re = new RegExp('^[1-8][0-7](0[1-9]|([1-8][0-9])|90)(0[1-9]|([1-9][0-9]))((18|19|20)\\\\d{2})(0[1-9]|(10|11|12))(([0-2][1-9])|10|20|30|31)\\\\d{3}[0-9Xx]$','g')
        return re.test(str)
    }else{
        console.error('请传参')
    }
}

 

以上是关于别百度正则了,一篇正则详解带你搞懂正则的主要内容,如果未能解决你的问题,请参考以下文章

别百度正则了,一篇正则详解带你搞懂正则

一篇文零基础带你搞懂回溯(万字:核心思维+图解+习题+题解思路+代码注释)

一篇文零基础带你搞懂回溯(万字:核心思维+图解+习题+题解思路+代码注释)

一篇文零基础带你搞懂回溯(万字:核心思维+图解+习题+题解思路+代码注释)

5分钟搞懂正则表达式!附“人话版”详解

一篇文搞懂webpack[零基础教学+手把手带你搞项目]