正则表达式 基础概念
正则表达式(regular expression)用来按照 给定模式 匹配文本
const regex = /xyz/i;
const regex = new RegExp('xyz', i);2
元字符
点字符
.:匹配除回车\r、换行\n、行分隔符\u2028和段分隔符\u2029以外的所有字符位置字符:
^表示字符串的开始位置,$表示字符串的结束位置选择符
|:表示 或关系 (OR),即cat|dog表示匹配cat或dog
转义符
12个需要转译的字符:^、.、[、$、(、)、|、*、+、?、{、\
正则表达式中那些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠
如果使用
RegExp方法生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次
new RegExp('1\+1').test('1+1')
// false
new RegExp('1\\+1').test('1+1')
// true2
3
4
5
特殊字符
\cX表示Ctrl-[X],其中的X是A-Z之中任一个英文字母,用来匹配控制字符[\b]匹配退格键U+0008,不要与\b混淆\n匹配换行键\r匹配回车键\t匹配制表符tabU+0009\v匹配垂直制表符U+000B\f匹配换页符U+000C\0匹配null字符U+0000\xhh匹配一个以两位十六进制数\x00-\xFF表示的字符\uhhhh匹配一个以四位十六进制数\u0000-\uFFFF表示的 Unicode 字符
预定义模式
\d匹配0-9之间的任一个数字,相当于[0-9]\D匹配所有0-9以外的字符,相当于[^0-9]\w匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]\W除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]\s匹配空格(包括换行符、制表符、空格符等),相等于[ \t\r\n\v\f]\S匹配非空格的字符,相当于[^ \t\r\n\v\f]\b匹配词的边界\B匹配非词边界,即在词的内部
字符类
表示有一系列字符可供选择,只要匹配其中一个就可以了所有可供选择的字符都放在方括号内,比如
[xyz]表示x、y、z之中任选一个匹配
脱字符 ^
脱字符只有在字符类的第一个位置才有特殊含义,否则就是字面含义
如果方括号内的第一个字符是
^,则表示除了字符类之中的字符,其他字符都可以匹配比如,[^xyz]表示除了x、y、z之外都可以匹配如果方括号内没有其他字符,即:
[^],就表示匹配一切字符,其中包括换行符相比之下,点号作为元字符.是不包括换行符的
const s = 'Please yes\nmake my day!';
s.match(/yes.*day/) // null
s.match(/yes[^]*day/) // [ 'yes\nmake my day']2
3
4
连字符 -
对于连续序列的字符,连字符 - 用来提供简写形式,表示字符的连续范围比如,[abc] 可以写成 [a-c],[0123456789] 可以写成 [0-9],同理 [A-Z] 表示26个大写字母
WARNING
由于存在ASCII编码顺序和常识顺序相悖的情况,不建议使用 -
重复类
模式的精确匹配次数,使用大括号
{}表示;
{n}表示恰好重复n次{n,}表示至少重复n次{n,m}表示重复不少于n次,不多于m次
/lo{2}k/.test('look') // true
const res = /lo{2, 5}k/.test('looook') // res: true2
3
量词符
?问号表示某个模式出现0次或1次,等同于{0,1}*星号表示某个模式出现0次或多次,等同于{0,}+加号表示某个模式出现1次或多次,等同于{1,}
贪婪模式
匹配直到下一个字符不满足匹配规则为止这被称为贪婪模式
?*+默认情况下都是最大可能匹配-贪婪模式
const s = 'aaa';
s.match(/a+/) // ["aaa"]2
如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个
?
const s = 'aaa';
s.match(/a+?/) // ["a"]2
组匹配
正则表达式的
()表示分组匹配,括号中的模式可以用来匹配分组的内容
/fred+/.test('fredd') // true
const res = /(fred)+/.test('fredfred') // res: true2
3
- 第一个模式 没有括号,
+表示重复字母d - 第二个模式 有括号,
+表示重复词fred
反向匹配
正则表达式内部,还可以用
\n引用括号匹配的内容,n是从1开始的自然数,表示对应顺序的括号
const tagName = /<([^>]+)>[^<]*<\/\1>/;
tagName.exec("<b>bold</b>")[1]
// 'b'
// 圆括号匹配尖括号之中的标签,而 \1 就表示对应的闭合标签2
3
4
5
非捕获组
?:x称为非捕获组(Non-capturing group),表示不返回该组匹配的内容,即匹配的结果中不计入这个括号
'abc'.match(/(?:.)b(.)/);
// ["abc", "c"]
// 正常匹配
const url = /(http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;
url.exec('http://google.com/');
// ["http://google.com/", "http", "google.com", "/"]
// 非捕获组匹配
const url = /(?:http|ftp):\/\/([^/\r\n]+)(\/[^\r\n]*)?/;
url.exec('http://google.com/');
// ["http://google.com/", "google.com", "/"]2
3
4
5
6
7
8
9
10
11
12
先行断言
x(?=y)称为先行断言(Positive look-ahead),x只有在y前面才匹配,y不会被计入返回结果先行断言中,括号里的部分是不会返回的
eg: 要匹配后面跟着百分号的数字,/\d+(?=%)/
'abc'.match(/b(?=c)/);
// ["b"]2
先行否定断言
x(?!y)称为先行否定断言(Negative look-ahead),x只有不在y前面才匹配,y不会被计入返回结果
eg: 要匹配后面跟的不是百分号的数字,/\d+(?!%)/
/\d+(?!\.)/.exec('3.14')
// ["14"]2