JavaScript Regular Expression:正则表达式(描述了字符串的模式对象)
实则是一种匹配模式,多用于描述要检索的文本;
简单的模式可以是一个字符,复杂的模式包括了更多的字符,并可用于解析、模板替换、格式检查等等;
正则表达式大大简化了操作: /pattern/modify ;pattern是需要进行匹配的字符串,modify则是对匹配模式的描述 (i, g, ig --用以改变原有的匹配模式,m(表示每一行单独来进行处理) )
常见的pattern匹配元字符如下:
\w :匹配字母、数字、下划线或者汉字;
\d:匹配数字 ; \D:匹配除了数字以外的其他字符(基本上都是这样的反义匹配规则)
. :匹配除换行符以外的所有字符 需要好好的来理解转义:‘\’ , 此时'\.' 代表着含义是普通的小数点
\s:匹配任意的空白符(空格,tab,换行符皆是)
^ :匹配字符串开头
$ :匹配字符串结尾
*:限定符,用来修饰前一个字符或者分组,表示匹配到的数量为任意个
+:限定度,一个或者多个,不断往后进行匹配(遇到不是的则会终止不会继续往后匹配,即只考虑连续的(如果匹配模式是默认的情况下))
常见的modify:
1、/g 表示该表达式将用来在输入字符串中查找所有可能的匹配,返回的结果可以是多个。如果不加/g最多只会匹配一个
2、/i 表示匹配的时候不区分大小写,这个跟其它语言的正则用法相同
3、/m 表示多行匹配。什么是多行匹配呢?就是匹配换行符两端的潜在匹配。影响正则中的^$符号
4、/s 与/m相对,单行模式匹配。
5、/e 可执行模式,此为PHP专有参数,例如preg_replace函数。
6、/x 忽略空白模式。
7. /y 粘连修饰符(sticky): 和g一样是全局匹配,后一次匹配从前一次匹配成功的下一个位置开始,但一旦有匹配失败的就会从头开始匹配。
和g不同的是,\g只要剩余的位置中存在要匹配的内容就会继续进行匹配,而\y要确保匹配要从剩下的第一个开始进行。注意:y隐含了头部匹配的标志 ^ -- \y常用语精准匹配(\g有时会跳过一些非法字符)
es6新增属性:flags -- 用于返回正则表达式的修饰符
初见正则表达式的魅力:
a.使用字面量来创建表达式:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //从a中匹配出所有数字 2 let a = 'cbw5v2sv256rev2r56'; 3 let nums = [...a].filter(f => !Number.isNaN(parseInt(f))); 4 console.log(nums.join('')); 5 6 //采用regExp: 7 console.log(a.match(/\d/g).join(''));
一般而言,正则表达式不能来识别变量,如果pattern想要用变量来替代的话,可以考虑来使用
eval()方法:用于计算或者解析js字符串代码,
如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 let hd = 'nnwvr154.com'; 2 console.log(/v/.test(hd)); 3 let b = 'v'; 4 console.log(eval(`/${b}/`).test(hd)); //等价于第二行
b.使用对象来创建正则表达式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //对象方式 2 let c = 'w'; 3 let f = 'cjwe123.com'; 4 let w = new RegExp(c, 'g'); //第一个参数pattern,第二个匹配模式,均可用变量来替换 5 console.log(w.test(f));
基本知识点:
(1).区分原子表和原子组:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //区分原子表和原子组 2 let test = '5521361'; 3 let reg = /[123456]/; 4 //原子表:相当于当个字符的选择符的集合 5 console.log(test.match(reg)); //[ '5', index: 0, input: '5521361', groups: undefined ] 6 //原子组:字符组的选择 7 console.log(test.match(/(52|61)/)); //[ '52', '52', index: 1, input: '5521361', groups: undefined ]
(2).转义的基本使用:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //转义的理解 2 let num = '12.34'; 3 console.log(num.match(/\d+\.\d/g)); 4 //区分'\d'和'\\d' 5 console.log('\\d' === 'd'); 6 console.log('\\d' + '---' + '\d'); 7 8 let url = 'https://www.liangye.com'; 9 console.log(url.match(/https?:\/\/\w+\.\w+\.\w+/g).join('')); // 末尾需要加上 + /g(不能只是/g),否则就会被识别为https://www.liangye.c
(3)..了解限定边界符:
' ^ ' :表示字符串开始 ; ' $ ' :表示字符串结尾;
在实际项目开发时二者常来结合来使用,表示匹配到的字符串及时开头也是结尾。
可见下面的一个小案例:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1.0"> 7 <title>边界符的使用</title> 8 </head> 9 10 <body> 11 <input type="text" id="user" /> 12 </body> 13 <script> 14 document.querySelector('#user') 15 .addEventListener('keyup', function() { 16 let flag = this.value.match(/^[a-z]{3,6}$/); //监测输入的内容是不是3~6位的字母 17 console.log(flag); 18 }); 19 </script> 20 21 </html>
输入:hello,可见:
(4).数值与空白元字符
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 let a = 'cnwj52541snj'; 2 console.log(a.match(/\D+/)); // +表示匹配一个或者多个,但此时并不是全局(即只会条件匹配遇到的第一个字符串) 3 //想要来匹配电话号码 4 let b = `良夜:086-123456789,随缘:010-989354623`; 5 console.log(b.match(/\d{3}-\d+/g)); //[ '086-123456789', '010-989354623' ]; 6 //在这里也可以通过原子表的方式来匹配电话号码 7 console.log(b.match(/[\d-]+/g)); //[ '086-123456789', '010-989354623' ]; 8 9 //较为复杂的匹配中文 --原子表的方式,加上^:表示除了里面的都匹配 10 console.log(b.match(/[^:\d-,]+/g));
(5).常见匹配模式
a. \m多行匹配修正符
1 let f = ` 2 #1 enc,200 # 3 #25 cner,481 # 4 #48925 cnerui,cjr3jf # 不符合 5 `; 6 let item = f.match(/^\s*#\d+\s+.+\s+#$/gm).map(v => { 7 v = v.replace(/\s*#\d+\s*/, '').replace(/\s*#\s*/, ''); 8 //利用解构 9 [name, price] = v.split(','); 10 return { name, price }; 11 }); 12 console.log(item); //[ { name: 'enc', price: '200' }, { name: 'cner', price: '481' } ]
(6).exec和lastindex的结合使用
lastindex属性:表示下一次正则匹配开始的位置,只有在全局模式下才起作用.
exec():对指定的字符串进行正则匹配,获取字符串中第一个与正则表达式相匹配的内容,并将匹配的内容和子匹配的结果存放在保存的数组中。
故:二者通常可结合来使用
代码如下:
// exec和lastindex的结合使用 let qwe = '%123%123%13'; let v = /%\w+/g; while (str = v.exec(qwe)) { console.log(str + '--' + v.lastIndex); }; /*%123--4 %123--8 %13--11*/
(7).断言匹配
详情见代码:
1 // 先行断言 x 只有在y前面才进行匹配 需写成 /x(?=y)/格式 2 //匹配%前面的数字 3 let ly = 'cnr122%525fe86%'; 4 let x = /\d+(?=%)/; 5 console.log(x.exec(ly)); //[ '122', index: 3, input: 'cnr122%525fe86%', groups: undefined ] 6 7 //先行否定匹配 在原有基础上加个 '!'和去掉 '='即可 --用于匹配不直接在y前面的x 8 //匹配不直接在%前面的数字 9 let y = /\d+(?!%)/g; 10 console.log(ly.match(y)); //[ '12', '525', '8' ] 11 12 //后行匹配 只匹配在y后面的x 格式: /(?<=y)x/ 有所不同:后行匹配会先去匹配x,再回去左边去匹配y的部分 13 //匹配%后面的数字 14 console.log(ly.match(/(?<=%)\d+/g)); //[ '525' ] 15 16 //后行否定匹配 用于匹配不直接在y后面的x(前面的当然可以匹配啦) 格式/(?<!y)x/ 17 console.log(ly.match(/(?<!%)\d+/g)); //[ '122', '25', '86' ]