首页 > 技术文章 > 正则表达式的基本使用

liangye 2020-08-05 02:01 原文

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.使用字面量来创建表达式:

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(''));
View Code

 一般而言,正则表达式不能来识别变量,如果pattern想要用变量来替代的话,可以考虑来使用

eval()方法:用于计算或者解析js字符串代码,

如下:

1 let hd = 'nnwvr154.com';
2 console.log(/v/.test(hd));
3 let b = 'v';
4 console.log(eval(`/${b}/`).test(hd)); //等价于第二行
View Code

b.使用对象来创建正则表达式

1 //对象方式
2 let c = 'w';
3 let f = 'cjwe123.com';
4 let w = new RegExp(c, 'g'); //第一个参数pattern,第二个匹配模式,均可用变量来替换
5 console.log(w.test(f));
View Code

 

基本知识点:

(1).区分原子表和原子组:

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 ]
View Code

 

(2).转义的基本使用:

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
View Code

 

(3)..了解限定边界符:

' ^ ' :表示字符串开始 ;  ' $ ' :表示字符串结尾;

在实际项目开发时二者常来结合来使用,表示匹配到的字符串及时开头也是结尾。

可见下面的一个小案例:

 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>
View Code

输入:hello,可见:

 

(4).数值与空白元字符

 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));
View Code

 

(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' ]

 

推荐阅读