比较好的学习资料:
正则表达式30分钟入门教程
简介 | 正则表达式30分钟入门教程
[JS相关的正则函数]
实用网站:Regex Vis
元字符
- 元字符
\b
匹配单词开头或结尾,并不匹配这些单词分隔字符中的任何一个,它只匹配一个位置.
js
console.log("AHello Hello!".search(/\bHello/i)) // 7
console.log('him,history,hi,high'.search(/\bhi\b/)) // 12
console.log("AHello Hello!".search(/\bHello/i)) // 7
console.log('him,history,hi,high'.search(/\bhi\b/)) // 12
- 元字符
.
:匹配除了换行符以外的任意字符 - 元字符
*
: 匹配的是数量,表示*
前面的字符可以重复0次或多次 - 元字符
+
: 重复1次或多次 - 元字符
?
: 重复0次或1次
js
console.log("hello Moxod".search(/\bMo.od\b/i)) // 6 【.代替任意字符】
console.log("hello Moooooood".search(/\bMo*d\b/i)) // 6 【*标识前一个字符重复n次】
console.log("hello".search(/m+/i)) // -1 【m重复1次】
console.log("hello m".search(/m+/i)) // 6 【m重复1次的位置】
console.log("hello".search(/m*/i)) // 0 【m重复0次或者多次】
console.log("hellom".search(/m*/i)) // 0 【m重复0次或者多次】
console.log("sexy".search(/x?/i)) // 0 【x重复0次或者1次,也就是可以有也可以没有】
console.log("sexxy".search(/x?/i)) // 0 【x重复0次或者1次,也就是可以有也可没有】
console.log("sexy".search(/x?/i)) // 0 【x重复0次或者1次】
console.log("156558".search(/1565?58/i)) // 0 【5重复0次或者1次,也就是前一个字符5可以有0个或者1个】
console.log("1565058".search(/1565?58/i)) // -1 【5重复0次或者1次,也就是可以匹配到 15658 、15658】
console.log("15658".search(/1565?58/i)) // 0 【5重复0次或者1次,也就是可以匹配到 15658 、15658】
console.log("hello Moxod".search(/\bMo.od\b/i)) // 6 【.代替任意字符】
console.log("hello Moooooood".search(/\bMo*d\b/i)) // 6 【*标识前一个字符重复n次】
console.log("hello".search(/m+/i)) // -1 【m重复1次】
console.log("hello m".search(/m+/i)) // 6 【m重复1次的位置】
console.log("hello".search(/m*/i)) // 0 【m重复0次或者多次】
console.log("hellom".search(/m*/i)) // 0 【m重复0次或者多次】
console.log("sexy".search(/x?/i)) // 0 【x重复0次或者1次,也就是可以有也可以没有】
console.log("sexxy".search(/x?/i)) // 0 【x重复0次或者1次,也就是可以有也可没有】
console.log("sexy".search(/x?/i)) // 0 【x重复0次或者1次】
console.log("156558".search(/1565?58/i)) // 0 【5重复0次或者1次,也就是前一个字符5可以有0个或者1个】
console.log("1565058".search(/1565?58/i)) // -1 【5重复0次或者1次,也就是可以匹配到 15658 、15658】
console.log("15658".search(/1565?58/i)) // 0 【5重复0次或者1次,也就是可以匹配到 15658 、15658】
.*
: 表示可以前一个字符可以重复0次或多次
js
console.log(" hi后面不远处跟着一个Lucy!".search(/\bhi\b.*\bLucy\b/i)) // 1
console.log(" hi后面不远处跟着一个Lucy!".search(/\bhi\b.*\bLucy\b/i)) // 1
\b
:匹配数字
js
console.log("哈哈1-122".search(/\d-\d/i)) // 2
console.log("哈哈1-122".search(/\d-\d/i)) // 2
{n}
:匹配n个前一字符{n,m}
:匹配n-m个前一字符{n,}
:匹配n-无限个前一字符\d+
:匹配n个数字
js
console.log('012000-4560899'.search(/\d{3}-\d{7}/i)) // 3
console.log('A012000-4560899'.search(/\d+-\d+/i)) // 1
console.log('012000-4560899'.search(/\d{3}-\d{7}/i)) // 3
console.log('A012000-4560899'.search(/\d+-\d+/i)) // 1
\s
:匹配任意的空白符、制表符tab、换行符、中文全角空格等(space)
js
console.log('aa '.search(/\s/i)) // 2
console.log('aa '.search(/\s/i)) // 2
\w
: 匹配字母数字下划线汉字等(word) \w汉字一般匹配不到。不同环境、语言不一样,例如js就匹配不到
js
console.log(' s汉化'.search(/\w/i))
console.log(' s汉化'.search(/\w/i))
^
: 匹配位置: 字符串的开头$
: 匹配位置: 字符串的结尾
js
console.log(/\d/.test(1)) // true
console.log(/^d{5,12}$/.test('dddddd')) // true
console.log(/^\d{5,12}$/.test('12345')) // true
console.log(/\d/.test(1)) // true
console.log(/^d{5,12}$/.test('dddddd')) // true
console.log(/^\d{5,12}$/.test('12345')) // true
[x-xx]
: - 表示字符区间,例如[0-9]
代表的含意与\d
就是完全一致的:一位数字。同理[a-z0-9A-Z_]也完全等同于\w
(如果只考虑英文的话)。
条件、分组
|
:分支条件
js
console.log(/^\d{5,12}|\d{2}$/.test('12')) // true
console.log(/^\d{5,12}|\d{2}$/.test('12345')) // true
console.log(/^(\d{5,12})|(\d{2})$/.test('12345')) // true
console.log(/^\d{5,12}|\d{2}$/.test('12')) // true
console.log(/^\d{5,12}|\d{2}$/.test('12345')) // true
console.log(/^(\d{5,12})|(\d{2})$/.test('12345')) // true
{}
小括号可以进行分组
js
console.log(/^(abc){2}$/.test('abcabc')) // true 【abc重复两次】
console.log(/^(abc){2}$/.test('abcabc')) // true 【abc重复两次】
反向
大写表示非的概念
\D
非数字\W
非字母下划线数字\B
非单词开始\S
非空格类
js
console.log(/^\D.*$/.test('1233')) // false
console.log(/^\D.*$/.test('abcabc')) // true
console.log(/^\W.*$/.test('1233a')) // false
console.log(/^\W.*$/.test(' ')) // true
console.log(/^\S.*$/.test('1233a')) // true
console.log(/^\S.*$/.test(' ')) // false
console.log(/^\B.*$/.test('1233a')) // false
console.log(/^\B.*$/.test(' ')) // true
console.log(/^\D.*$/.test('1233')) // false
console.log(/^\D.*$/.test('abcabc')) // true
console.log(/^\W.*$/.test('1233a')) // false
console.log(/^\W.*$/.test(' ')) // true
console.log(/^\S.*$/.test('1233a')) // true
console.log(/^\S.*$/.test(' ')) // false
console.log(/^\B.*$/.test('1233a')) // false
console.log(/^\B.*$/.test(' ')) // true
[^x]
除了字母x外的字符[^xyz]
除了字母xyz外的字符
js
console.log(/^[^x].*$/.test('1233a')) // true
console.log(/^[^x].*$/.test('xxx')) // false
console.log(/^[^xyz].*$/.test('xxxxyycc')) // false
console.log(/^[^xyz].*$/.test('acc')) // true
console.log(/^[^xyz].*$/.test('aaxyz')) // true【字符串是不x/y/z开头的,故也满足】
console.log(/^[^x].*$/.test('1233a')) // true
console.log(/^[^x].*$/.test('xxx')) // false
console.log(/^[^xyz].*$/.test('xxxxyycc')) // false
console.log(/^[^xyz].*$/.test('acc')) // true
console.log(/^[^xyz].*$/.test('aaxyz')) // true【字符串是不x/y/z开头的,故也满足】
后向引用
略
断言
js
//js提取 `答案1`和`答案2`
var testString2 = `*****
我是一个问题
答案1
答案2
*****`;
var res = testString2.match(/(?<=\n我是一个问题)[\s\S]*?(?=\*{5})/g); //返回数组
console.log(res); // [ '\n答案1\n答案2\n' ]
//js提取 `答案1`和`答案2`
var testString2 = `*****
我是一个问题
答案1
答案2
*****`;
var res = testString2.match(/(?<=\n我是一个问题)[\s\S]*?(?=\*{5})/g); //返回数组
console.log(res); // [ '\n答案1\n答案2\n' ]
js
let reg = /POLYGON\((.*?)\)/gi;
let res = "POLYGON((118.257206432 35.142103492,118.261146368 35.1419743060001,118.261430013 35.1417178180001,118.260999498 35.137444895,118.260715327 35.1372872520001,118.256472888 35.1374869860001,118.257093814 35.1420241000001,118.257206432 35.142103492)),POLYGON((118.261576135 35.1385784340001,118.266236568 35.1384064650001,118.266269116 35.1384018200001,118.266129093 35.1371199160001,118.266007014 35.1370334690001,118.261688791 35.137240954,118.261460704 35.137432776,118.261576135 35.1385784340001))".match(reg)
console.log(res)
let reg = /POLYGON\((.*?)\)/gi;
let res = "POLYGON((118.257206432 35.142103492,118.261146368 35.1419743060001,118.261430013 35.1417178180001,118.260999498 35.137444895,118.260715327 35.1372872520001,118.256472888 35.1374869860001,118.257093814 35.1420241000001,118.257206432 35.142103492)),POLYGON((118.261576135 35.1385784340001,118.266236568 35.1384064650001,118.266269116 35.1384018200001,118.266129093 35.1371199160001,118.266007014 35.1370334690001,118.261688791 35.137240954,118.261460704 35.137432776,118.261576135 35.1385784340001))".match(reg)
console.log(res)
- 零宽度正预测先行断言
(?=exp)
- 零宽负向先行断言,又称负向向前查找
(?!exp)
似乎相当于?=exp
的取反
js
let x1 = `sinM.`.match(/sin(?=M\.)/g); // ["sin"]
let x2 = `M.sin`.match(/sin(?=M\.)/g); // null
console.log(x1)
console.log(x2)
let x3 = `sinM.`.match(/sin(?!M\.)/g); // ["sin"]
let x4 = `M.sin`.match(/sin(?!M\.)/g); // null
console.log(x3) // null
console.log(x4) // ["sin"]
let x1 = `sinM.`.match(/sin(?=M\.)/g); // ["sin"]
let x2 = `M.sin`.match(/sin(?=M\.)/g); // null
console.log(x1)
console.log(x2)
let x3 = `sinM.`.match(/sin(?!M\.)/g); // ["sin"]
let x4 = `M.sin`.match(/sin(?!M\.)/g); // null
console.log(x3) // null
console.log(x4) // ["sin"]
- 零宽度正回顾后发断言
(?<=exp)
正向向后查找 - 零宽负向后行断言,又称负向向后查找
(?<=exp)
负向向后查找
js
let x1 = `sinM.`.match(/(?<=M\.)sin/g); // ["sin"]
let x2 = `M.sin`.match(/(?<=M\.)sin/g); // null
console.log(x1) // null
console.log(x2) // [ 'sin' ]
let x3 = 'sinM.'.match(/(?<!M\.)sin/g); // ["sin"]
let x4 = 'M.sin'.match(/(?<!M\.)sin/g); // null
console.log(x3) // [ 'sin' ]
console.log(x4) // null
let x1 = `sinM.`.match(/(?<=M\.)sin/g); // ["sin"]
let x2 = `M.sin`.match(/(?<=M\.)sin/g); // null
console.log(x1) // null
console.log(x2) // [ 'sin' ]
let x3 = 'sinM.'.match(/(?<!M\.)sin/g); // ["sin"]
let x4 = 'M.sin'.match(/(?<!M\.)sin/g); // null
console.log(x3) // [ 'sin' ]
console.log(x4) // null
举例
\ba\w*\b
匹配单词以a开头+任意数量的数字、字母、下换线,截止到单词结尾
js
console.log('sss '.search(/\ba\w*\b/i)) // -1
console.log('asss '.search(/\ba\w*\b/i)) // 0
console.log('sss '.search(/\ba\w*\b/i)) // -1
console.log('asss '.search(/\ba\w*\b/i)) // 0
.*?
匹配任意数量的重复,但是在能使整个匹配成功的前提下使用最少的重复a.*?b
匹配最短的,以a开始,以b结束的字符串。如果把它应用于aabab的话,它会匹配aab(第一到第三个字符)和ab(第四到第五个字符)
js
console.log('aabab'.match(/a.*?b/g)) // [ 'aab', 'ab' ]
console.log('aabab'.match(/a.*b/g)) // [ 'aabab' ]
console.log('aabab'.match(/a.*?b/g)) // [ 'aab', 'ab' ]
console.log('aabab'.match(/a.*b/g)) // [ 'aabab' ]
- 贪心匹配/非贪心匹配的举例,例如想将把第二次出现的下划线前的字符串都去掉。例如"ab_cc_mmmm"提取出"mmmm" , "ab_cc_aa_cc"提取出"aa_cc"
originCode.replace(/^(.+?)_(.+?)_/, '');
originCode.replace(/^(.+?)_(.+?)_/, '');