正则表达式 基础概念
正则表达式(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')
// true
2
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: true
2
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: true
2
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