语法
\d
可以匹配一个数字,等价于[0-9]
\w
可以匹配一个单字字符 (字母、数字或者下划线) ,等价于[A-Za-z0-9_]
\W
匹配一个非单字字符,等价于[^A-Za-z0-9_]
.
可以匹配一个任意字符 ,换行符除外\s
匹配一个空白字符,包括空格、制表符、换页符和换行符\S
匹配一个非空白字符*
表示任意个字符,等价于{0,}
+
表示至少一个字符,等价于{1,}
?
表示0个或1个字符,等价于{0,1}
{n}
表示n个字符{n,m}
表示n-m
个字符\
转义(x)
普通分组,匹配'x'
并且记住匹配项(?<组名>RegExp)
具名组,使用$<组名>
引用具名组[xyz]
一个字符集合[^xyz]
一个反向字符集A|B
可以匹配A或B^
表示行的开头或非的意思$
表示行的结束
分组(或捕获组)
正则表达式通过使用括号将表达式分为不同的分组,识别的方法是通过从左至右搜寻左半括号,遇到第一个左半括号时,则该左半括号与对应的右半括号所包含的内容即为第一分组,以此类推 。
例如,在表达式((A)(B(C)))
,有四个这样的组:((A)(B(C)))、(A)、(B(C))、(C)
具名组
字符串替换时,使用
$<组名>
引用具名组1
2
3let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
'2015-01-02'.replace(re, '$<day>/$<month>/$<year>');在正则表达式内部引用某个“具名组匹配”,可以使用
\k<组名>
,或者数字引用(\1
)1
2
3
4
5const RE_TWICE = /^(?<word>[a-z]+)!\k<word>!\1$/;
RE_TWICE.test('abc!abc!abc') // true
RE_TWICE.test('abc!abc!ab') // false
位置类元数据
(exp)
:目标字符串需要匹配exp
,并将该分组匹配的子文本保存到自动命名的组里;
(?<name>exp)
:目标字符串需要匹配exp
,并将该分组匹配的子文本保存到名称为name
的组里,也可以写成(?'name'exp)
;
(?:exp)
:目标字符串需要匹配exp
,该括号所包括的内容不会被作为一个分组对待,该表达式与(exp)
在效果上其实应该是没有区别的,区别只是是否算作一个分组及是否保存匹配的子文本。
(?=exp)
:定义目标字符串结束位置要求,即紧随目标字符串后面出现的字符串需要匹配上exp
表达式,该字符串不会被计入目标字符串,表达中出现的括号也不会被视作一个分组;
(?<=exp)
:定义目标字符串起始位置要求,即紧邻目标字符串前面出现的字符串需要匹配上exp
表达式,该字符串不会被计入目标字符串,表达中出现的括号也不会被视作一个分组;
(?!exp)
:定义目标字符串结束位置要求,即紧随目标字符串后面出现的字符串不能匹配上exp
表达式,该字符串不会被计入目标字符串,表达中出现的括号也不会被视作一个分组;效果上与(?=exp)
表示的情况刚好相反;
(?<!exp)
:定义目标字符串起始位置要求,即紧邻目标字符串前面出现的字符串不能匹配上exp
表达式,该字符串不会被计入目标字符串,表达中出现的括号也不会被视作一个分组;效果上与(?<=exp)
表示的情况刚好相反;
1 | str.replace(/(\d)(?=(?:\d{3})+$)/g, '$1,'); // 千分位 |
贪婪匹配
贪婪匹配指的是:匹配的子串是最长的,如果符合条件,就一直匹配,返回最长的匹配子串。
非贪婪匹配:如果匹配成功,就返回子串,而不继续向下匹配了,用法就是在量词后面加上一个?
。
1 | var str = "aaabbb"; |