正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式一般被用来检索、替换那些符合某个模式(规则)的文本。正则表达式
简单的说,就是按照某种规则去匹配符合条件的字符串。
Regexper:https://regexper.com/函数
实例化
RegExp
的两种方式。
两种方式定义RegExp对象。工具
let reg = /[a-z]{3}/gmi; let reg = /[a-z]{3}/g; let reg = /[a-z]{3}/m; let reg = /[a-z]{3}/i;
g
global 表明全局搜索。若是不添加,搜索到第一个匹配中止。m
Multi-Line 表明多行搜索。i
ignore case 表明大小写不敏感,默认大小写敏感。let reg = new RegExp('\\bis\\b', 'g');
由于JavaScript字符串中\
属于特殊字符,须要转义。prototype
把元字符看成转义字符。
正则表达式有两种基本字符类型组成。3d
表示本来意义上是什么字符,就是什么字符。code
是在正则表达式中有特殊含义的非字母字符。* + ? $ ^ . | \ ( ) { } [ ]
regexp
字符 | 含义 |
---|---|
\t |
水平制表符 |
\v |
垂直制表符 |
\n |
换行符 |
\r |
回车符 |
\0 |
空字符 |
\f |
换页符 |
\cX |
控制字符,与X对应的控制字符(Ctrl + X) |
相似于转义字符。对象
表示符合某种特性的字符类别。
使用元字符[]
能够构建一个简单的类。
所谓类是指符合某些特性的对象,一个泛指,而不是某个字符。索引
表达式[abc]
把字符a
或b
或c
归为一类,表达式能够匹配这一类中的任意一个字符。ip
// replace() 方法用于在字符串中用一些字符替换另外一些字符,或替换一个与正则表达式匹配的子串。 'a1b2c3d4e5'.replace(/[abc]/g, '0'); //010203d4e5
咱们想要替换不是abc
中任意一个字符的字符。
// 元字符 ^ 建立一个 反向类/负向类 'abcdefg'.replace(/[^abc]/g, '0'); //abc0000
匹配这一个范围内的字符。
若是咱们想要匹配数字0-9
,那么咱们可能会这样写[0123456789]
。
若是咱们想要匹配26
个字母,那么咱们可能会这样写[abcdefghijklmnopqrstuvwxyz]
。
这样略显麻烦,因此才会有范围类。
// 替换全部数字 'a1c2d3e4f5'.replace(/[0-9]/g, 'x'); //axcxdxexfx // 替换全部小写字母 'a1c2d3e4f5'.replace(/[a-z]/g, 'x'); //x1x2x3x4x5 // []组成的类内部是能够连写的。替换全部大小写字母 'a1C2d3E4f5G6'.replace(/[a-zA-Z]/g, '*'); //*1*2*3*4*5*6
若是我想替换数字,而且连带-
符号也一块儿替换呢?
// 替换全部数字和横杠 '2018-5-21'.replace(/[0-9-]/g, '*'); //*********
一些已经定义的类,能够直接使用。
字符 | 等价类 | 含义 |
---|---|---|
. |
[^\r\n] |
除了回车、换行以外的全部字符 |
\d |
[0-9] |
数字字符 |
\D |
[^0-9] |
非数字字符 |
\s |
[\t\n\x0B\r] |
空白符 |
\S |
[^\t\n\x0B\r] |
非空白符 |
\w |
[a-zA-Z_0-9] |
单词字符(字母、数字、下划线) |
\W |
[^a-zA-Z_0-9] |
非单词字符 |
替换一个 ab
+ 数字
+ 任意字符
的字符串
// 写法1 'ab0c'.replace(/ab[0-9][^\r\n]/g, 'TangJinJian'); //TangJianJian // 写法2 'ab0c'.replace(/ab\d./g, 'TangJinJian'); //TangJianJian
字符 | 含义 |
---|---|
^ |
以xxx开始(不在中括号内时的含义) |
$ |
以xxx结束 |
\b |
单词边界 |
\B |
非单词边界 |
我想替换的字符串,属于那种只在开头出现的。
'YuYan is a boy, YuYan'.replace(/^YuYan/g, 'TangJinJian'); //TangJinJian is a boy, YuYan
我想替换的字符串,属于那种只在结尾出现的。
'YuYan is a boy, YuYan'.replace(/YuYan$/g, 'TangJinJian'); //YuYan is a boy, TangJinJian
单词边界例子。
// 替换全部is为0 'This is a man'.replace(/is/g, '0'); //Th0 0 a man // 替换全部is前面带有单词边界的字符串 'This is a man'.replace(/\bis/g, '0'); //This 0 a man // 替换全部is前面没有单词边界的字符串 'This is a man'.replace(/\Bis\b/g, '0'); //Th0 is a man
用来处理连续出现的字符串。
字符 | 含义 |
---|---|
? |
出现零次或一次(最多出现一次) |
+ |
出现一次或屡次(至少出现一次) |
* |
出现零次或屡次(任意次) |
{n} |
出现n次 |
{n,m} |
出现n到m次 |
{n,} |
至少出现n次 |
我想替换字符串中连续出现10
次的数字为*
。
'1234567890abcd'.replace(/\d{10}/, '*'); //*abcd
我想替换字符串中的QQ号码。
'个人QQ是:10000'.replace(/[1-9][0-9]{4,}/, '12345678'); //个人QQ是:12345678
尽量多的匹配。
有这样的一种场景下的正则表达式,/\d{3,6}/
该替换3个数字仍是6个数字呢,四、5个数字?
// 贪婪模式会尽量的往多的方面去匹配 '123456789'.replace(/\d{3,6}/, 'x'); //x789 '123456789'.replace(/\d+/, 'x'); //x '123456789'.replace(/\d{3,}/, 'x'); //x
尽量少的匹配。
若是咱们想要最低限度的替换呢?
// 非贪婪模式使用 ? 尽量的往少的方面去匹配 '12345678'.replace(/\d{3,6}?/g, 'x'); //xx78 '123456789'.replace(/\d{3,6}?/g, 'x'); //xxx
由于有g
标志,会匹配这段字符串里全部符合规则的字符串。
第一个规则/\d{3,6}?/g
,12345678
中有两个符合条件的字符串,是123
和456
。因此替换结果是xx78
。
第二个规则/\d{3,6}?/g
,123456789
中有三个符合条件的字符串,是123
、456
和789
。因此替换结果是xxx
。
括号里的一些规则,分为一组。
我想替换连续出现3次的字母
和数字
。
//没有分组的状况下,后面的量词,只是表示匹配3次数字。 'a1b2d3c4'.replace(/[a-z]\d{3}/g, '*'); //a1b2d3c4 //有分组的状况下,分组后面的量词,表示符合这个分组里规则的字符串,匹配3次。 'a1b2d3c4'.replace(/([a-z]\d){3}/g, '*'); //*c4
分组里有两种规则,只要知足其中一种便可匹配。
//我想把ijaxxy和ijcdxy都替换成* 'ijabxyijcdxy'.replace(/ij(ab|cd)xy/g, '*'); //**
能够把分组视为变量,来引用。
//我想把改变年月日之间的分隔符 '2018-5-22'.replace(/(\d{4})-(\d{1,2})-(\d{1,2})/g, '$1/$2/$3'); //2018/5/22 //我想替换日期,而且更改顺序 '2018-5-22'.replace(/(\d{4})-(\d{1,2})-(\d{1,2})/g, '$2/$3/$1'); //5/22/2018
忽略掉分组,不捕获分组,只须要在分组内加上?:
// 忽略掉匹配年的分组后,匹配月的分组变成了$1,日的分组变成了$2 '2018-5-22'.replace(/(?:\d{4})-(\d{1,2})-(\d{1,2})/g, '$1/$2/$3'); //5/22/$3
正则表达式从文本头部向尾部开始解析,文本尾部方向,称为“前”。
前瞻就是在正在表达式匹配到规则的时候,向前检查是否符合断言,后顾/后瞻方向相反。
JavaScript不支持后顾。
符合和不符合特定断言称为确定/正向
匹配和否认/负向
匹配。
名称 | 正则 | 含义 |
---|---|---|
正向前瞻 | exp(?=assert) |
|
负向前瞻 | exp(?!assert) |
|
正向后顾 | exp(?<=assert) |
JavaScript不支持 |
负向后顾 | exp(?<!assert) |
JavaScript不支持 |
有这样一个单词字符
+数字
格式的字符串,只要知足这种格式,就把其中的单词字符替换掉。
'a1b2ccdde3'.replace(/\w(?=\d)/g, '*'); //*1*2ccdd*3
有这样一个单词字符
+非数字
格式的字符串,只要知足这种格式,就把前面的单词字符替换掉。
'a1b2ccdde3'.replace(/\w(?!\d)/g, '*'); //a*b*****e*
global
是否全文搜索,默认false
。ignore case
是否大小写敏感,默认是false
。multiline
多行搜索,默认值是false
。lastIndex
是当前表达式匹配内容的最后一个字符的下一个位置。source
正则表达式的文本字符串。
let reg1 = /\w/; let reg2 = /\w/gim; reg1.global; //false reg1.ignoreCase; //false reg1.multiline; //false reg2.global; //true reg2.ignoreCase; //true reg2.multiline; //true
用来查看正则表达式与指定的字符串是否匹配。返回true
或false
。
let reg1 = /\w/; reg1.test('a'); //true reg1.test('*'); //false
加上g
标志以后,会有些区别。
let reg1 = /\w/g; // 第一遍 reg1.test('ab'); //true // 第二遍 reg1.test('ab'); //true // 第三遍 reg1.test('ab'); //false // 第四遍 reg1.test('ab'); //true // 第五遍 reg1.test('ab'); //true // 第六遍 reg1.test('ab'); //false
实际上这是由于RegExp.lastIndex
。每次匹配到以后,lasgIndex
会改变。lastIndex
是正则表达式的一个可读可写的整型属性,用来指定下一次匹配的起始索引。
let reg = /\w/g; // 每次匹配到,就会把lastIndex指向匹配到的字符串后一个字符的索引。 while(reg.test('ab')) { console.log(reg.lastIndex); } // 1 // 2
reg.lastIndex
初始时为0
,第一个次匹配到a
的时候,reg.lastIndex
为1
。第二次匹配到b
的时候,reg.lastIndex
为2
。