RegExp


教程

教程:链接
正则进阶:链接
正则github练习:链接

RegExp特殊字符

符号 含义
\d [0-9] 表示数字字符
\w [a-zA-Z0-9_] 表示数字,大小写字母及下划线
\s [\t\n\x0B\f\r] 表示空白符
[a-zA-Z0-9] 表示大小写字母,数字字符
\b 表示单词边界
. 表示除回车符换行符的所有字符
* 出现0次或多次(任意次)
+ 出现1一次或多次(最少出现一次)
? 出现0次或1次(最多出现一次)
x{3} 表示x字符出现3次
^ 以什么字符做为开头
$ 以什么字符做为结尾
[^abc] 表示不是abc的所有字符
abc{3,5}? ?在量词后面表示非贪婪模式,若字符串匹配,c取3个
(abc){10} 表示abc字符连续出现10次
abc(?=def) 匹配后面为def的abc

RegExp 相关方法

RegExp.prototype.test(str)
1
2
3
4
//测试字符串参数中是否存正则表达式模式,如果存在则返回true
var reg = /\d+\.\d{1,2}$/g;
reg.test('123.45'); //true
reg.test('34.5678'); //false

RegExp.prototype.exec(str)

原理

使用结果可以等价于String.prototype.match()的非全局匹配,在string中找到了匹配的文本,则返回一个包含这些文本的数组,否侧返回null。不区分是否全局匹配,只匹配一次

1
2
3
4
5
var result = /(\d+)-(\w+)/.exec('12-ab');
console.log(result) // --> ["12-ab", "12", "ab", groups: undefined, index: 0, input: "12-ab", length: 3]
"12-ab":整个正则表达式匹配的文本
"12":第一个子表达式匹配的文本
"ab":第二个子表达式匹配的文本...以此类推,groups是否为全局匹配,index为匹配位置,input为原字符串,length为整个匹配文本和子表达式匹配文本

String.prototype.replace(str)

使用情景
1
2
3
4
5
6
7
8
9
10
11
1、当未找到匹配项的时候,返回原始字符串。
'aaaa'.replace('aaa', 'b') //"ba"
2、当第一项为字符串或者非全局reg时,只替换找到第一个的
'aaaa'.replace('a', 'b') //"baaa"
'aaaa'.replace(/\w/, 'b') //"baaa"
3、当为全局reg时,替换全部
'aaaa'.replace(/\w/g, 'b') //"bbbb"
4、当为函数时
'aaaa'.replace(/\w/g, function(value) {
return value.toUpperCase();
}); // "AAAA"
特殊情况$
1
2
3
4
5
6
$1,$2,$3...$99   第一个到第99子表达式相匹配的文本。
实际是RegExp.$1, RegExp.$2,...RegExp.$99
$& 与 regexp相匹配的子串
$` 位于匹配子串左侧的文本
$' 位于匹配子串右侧的文本
$$ 直接量符号
案例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
案例1:
'aa11AA'.replace(/([a-z]+)/g, '$1') // 'aa11AA' 将aa替换为aa,所以不变
'aa11AA'.replace(/([a-z]+)/g, '$1,') // 'aa,11AA' 将aa,替换为aa
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$1'); // "aa" 将aa11AA全部替换为aa,等价于
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, RegExp.$1); // "aa" 将aa11AA全部替换为aa
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$1,'); // "aa,"
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$2'); // "11"
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$3'); // "AA"
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$4'); // "$4" //因为没有$4所以是替换
案例2:
'aa11AA'.replace(/([a-z]+)(\d+)([A-Z]+)/g, '$&'); //"aa11AA" //找到所有相匹配的子串
案例3:
'aa11AA'.replace(/(\d+)/g, '$`'); //"aaaaAA" //把匹配的子串的左侧的文本替换到匹配子串
案例4:
'aa11AA'.replace(/(\d+)/g, "$'"); //"aaAAAA" //把匹配的子串的右侧的文本替换到匹配子串
案例5:
'aa11AA'.replace(/(\d+)/g, '$$'); //"aa$AA" //匹配子串设置为$

特殊字符

列表
1
2
\b  //匹配一个字边界,即字与空格间的位置,空格,换行符甚至中文都算边界
\B //非字边界匹配
解释说明
1
2
3
4
5
(/\bmo/g).test("moon")  //true 意思是mo的左边是边界,即m左边没有任何东西
(/mo\b/g).test("moon") //false 意思是mo的右边是边界,即mo右边没有任何东西
(/\bmo\b/g).test("mo") //true 意思是mo的左右边是边界,即mo左右边没有任何东西

(/mo\B/g).test("moon") //true 意思是mo的右边不是边界

分支条件

含义

‘|’讲不同的规则分隔开,表示或,但是和’||’符号不同,这个是将正则整体分开

解释说明
1
2
3
var a = /^0\d{2}-\d{8}$|^0\d{3}-\d{7}$/  
a.test('012-123456789') //false
a.test('012-12345678') //true

分组

含义

()表示分组
注意:正常的()需要转义

解释说明
1
2
var a = /(\d{1,3}\.){3}\d{1,3}/
a.test('256.300.888.999') //true
联合使用
1
2
3
4
5
6
7
8
9
10
1、重复使用
var b = /\b(\w+)(\d+)\b\s+\1\2\b/ // \1表示(w+),\2表示(\d+),并且要和前一模一样
b.test('go1 go1') //true
b.test('go1 go2') //false

2、重命名使用
(?<Word>\w+)或(?'Word'\w+)
var b = /\b(?<word>\w+)(?<dialog>\w+)\b\s+\k<word>\k<dialog>\b/
b.test('go1 go1') //true
b.test('go1 go2') //false

反义

列表
1
2
3
4
5
6
\W  匹配任意不是字母,数字,下划线字符
\S 匹配任意不是空白符的字符
\D 匹配任意非数字的字符
\B 匹配不是单词开头或结束的位置
[^x] 匹配除了x以外的任意字符
[^aeiou] 匹配除了aeiou这几个字母以外的任意字符

末尾不跟字母

使用场景
1
2
3
4
5
6
// 匹配q后面不是字母u的字母q的单词。
/\b\w*q[^u]\w*\b/.test('eqsal') // true
/\b\w*q[^u]\w*\b/.test('equal') // false
/\b\w*q[^u]\w*\b/.test('eq') // false
// 因为[^u]表示后面跟的不是u但必须要跟一个东西,所以q出现在单词的结尾的话就不匹配。
// 正确的为\b\w*q(?!u)\w*\b
记忆方法
1
?表示怀疑,?=表示后面紧跟,?!表示后面不能跟,?<=表示前面紧跟,?<!表示前面不紧跟
解释说明
1
2
3
4
5
6
\d{3}(?=a)   //匹配三位数字,而且这三位数字的后面必定是a
\d{3}(?!\d) //匹配三位数字,而且这三位数字的后面不能是数字
\b((?!abc)\w)+\b //匹配不包含连续字符串abc的单词
(?<![a-z])\d{7} //匹配前面不是小写字母的七位数字
(?<=<(\w+)>).* //匹配前面是html标签的
(?<=<(\w+)>).*(?=<\/\1>) //匹配不包含属性的简单HTML标签内里的内容