别百度正则了,一篇正则详解带你搞懂正则
Posted 小小码农,可笑可笑
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了别百度正则了,一篇正则详解带你搞懂正则相关的知识,希望对你有一定的参考价值。
目录
元字符列表:( [ { \\ ^ $ | ) ] } ? * + .
语法模式
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('请传参')
}
}
以上是关于别百度正则了,一篇正则详解带你搞懂正则的主要内容,如果未能解决你的问题,请参考以下文章
一篇文零基础带你搞懂回溯(万字:核心思维+图解+习题+题解思路+代码注释)
一篇文零基础带你搞懂回溯(万字:核心思维+图解+习题+题解思路+代码注释)