leoyuan.github.io
leoyuan.github.io copied to clipboard
JavaScript之正则表达式
注:此博文意在记录一些常用到的JS正则知识点,并不想写成一篇大而全的JS正则手册。
1. 基础知识
1.1 \w, \W, \s, \S 和.
\w 所有数字、字母和下划线
\W 所有非数字和字母
\s 所有空白字符,如\t \r \n等
\S 所有非空白字符,包括\w以及!@#$%^&_()等字符
. 所有除 _回车换行外* 的字符
[\s\S]+
等价于 [\w\W]+
,大多数情况下等价于.+
,如
(.
号除了不能匹配\n
,其他字符都能匹配)
/^.+$/.test("a\nb") // false
/^.+$/m.test("a\nb") // true
/^[\w\W]+$/.test("a\nb") // true
/^[\s\S]+$/.test("a\nb") // true
1.2 特殊字符转义
通过\
来转,如/\\/
可以匹配到字符串中的/
号,/\./
可以匹配到字符串中的.
号等
1.3 [ ]中的特殊字符不需要转义
如/[.^$*]/
可以匹配到字符串中的.
, ^
, $
, *
等字符
1.4 JS中跟正则相关的方法
共六个,包括正则对象两个,test
, exec
, 和字符串对象四个,replace
, search
, match
, split
2. 分组捕获/不捕获
使用()
可捕获匹配到的字符串,如/(\w+)/.exec("testString")
,输出RegExp.$1
,可得到testString
有时候分组了,但是觉得捕获没有什么意义,基于效率考量,可以不捕获,语法为(?:)
,如
/(?:\w+)/.exec("testString")
,输出RegExp.$1
,得到空字符串
3. 贪婪/不贪婪,又称回逆
/(.+)source/.exec('webapp/source')
,分组匹配到了整个字符串,那假如我们只想匹配source
前边的那一段呢?
这就取决于正则匹配时是贪婪地一直匹配下去,还是适可而止,遇到后边的source
匹配段时,回逆回来。
怎么控制它的贪婪?在量词后边加上?
号就好了,如/(.+?)source/.exec('webapp/source')
,即可保证分组匹配到的是webapp/
。
同理\w*?
4. 反向引用
如需要匹配之前某个分组已经捕获的字符串,可以用反向引用,如捕获HTML标签名,
/^<(\w+)\s.*>(?:<\/\1>)$/
来匹配<script src=''></script>
中的script
字符串
\1
代表第一个捕获的分组,\2
代表第二个捕获的分组,以此类推。
5. 前瞻(positive/negative lookahead)
因为正则解析引擎是从字符串前端往后端扫描,所有对于正则解析引擎来说,往前扫描即是往字符串后端扫描的意思。
如需要根据之后的内容 是 某个字符串来决定是否匹配时,可以用到正向前瞻功能,语法是?=
,如
(\w+)(?=source)
,即可匹配字符串中source
段之前的部分,
如需要根据之后的内容 不是 某个字符串来决定是否匹配时,可以用到负向前瞻功能,语法是?!
,如
/bed(?!room)/
,可以匹配到bedhaha
,但是不能匹配到bedroom
。
6. 后顾(positive/negative lookbehind)(最新版JS正则引擎才支持)
与5类似,唯一的不同是,前瞻是根据 之后的字符串 来决定是否予以匹配,而后顾是根据 之前的字符串 来决定。
正向后顾的语法是?<=
,如/(?<=aaa)bbb/
,即可匹配bbb
之前为aaa
的字符串,如caaabbb
负向后顾的语法是?<!
,如/(?<!aaa)bbb/
,即可匹配bbb
之前不为aaa
的字符串,如xbbb
更多例子
Matching Numeric Ranges with a Regular Expression Matching Floating Point Numbers with a Regular Expression How to Find or Validate an Email Address Regular Expression Matching a Valid Date Matching Whole Lines of Text Deleting Duplicate Lines From a File Find Two Words Near Each Other