学习使用正则表达式
正则表达式很早就有了解,有需要的时候,也能借助搜索引擎简单使用一下,但似乎从来没有比较系统的学习过,所以这段时间看了一些资料,记录一下正则表达式的一些概念、用法以及 JS 中的相关 API。
字符组
字符组包含了要匹配字符的所有可能情况,使用[]
表示,具体有如下三种描述方法
- 列举。即列举所有可能字符,如
[abc]
- 范围。即使用范围表示所有可能字符,如
[a-z]
- 取反。在上面两种写法的基础上,在前面加上
^
表示取反逻辑,如[^abc]
对于常见的字符组,正则引擎内置了一些简写
\d
表示[0-9]
\D
表示[^0-9]
\w
表示[0-9a-zA-Z_]
\W
表示[^0-9a-zA-Z_]
\s
表示[ \t\v\n\r\f]
,\v 是垂直制表符,\f 是换页符\S
表示[^ \t\v\n\r\f]
.
表示[^\n\r\u2028\u2029]
表示几乎所有字符,除了换行符、回车符、行分隔符、段分隔符
量词
量词用来描述某个模式出现的次数,有两种描述方法
{m,}
表示至少出现 m 次{m}
表示恰好出现 m 次
同样,对于常用的量词,引擎内置了一些简写
?
表示{0, 1}
+
表示{1,}
*
表示{0,}
贪婪与非贪婪
先看一个例子
var regex = /\d{1,3}/g;
var string = "1 12 123 1234";
console.log(string.match(regex));
// -> ["1", "12", "123", "123", "4"]
\d{1,3}
的意思是数字出现 1 到 3 次,但从结果可以观察到,这个模式会尽量多的匹配数字,即能匹配 3 个就不匹配两个,能匹配两个就不匹配一个。这种行为就是贪婪匹配。那么什么是非贪婪匹配的,在原来的例子上简单修改一下。
var regex = /\d{1,3}?/g;
var string = "1 12 123 1234";
console.log(string.match(regex));
// -> ["1", "1", "2", "1", "2", "3", "1", "2", "3", "4"]
匹配出来的结果都是一个数字,即能匹配一个就不匹配两个。通过上面的例子可以得到两个结论
- 量词默认是贪婪的
- 在模式后面加
?
可以将贪婪匹配变成非贪婪匹配
选择分支
语法是(p1|p2)
,表示模式 p1 或模式 p2。看个例子
var regex = /\d{3}|\d{5}/g;
var string = "12345";
console.log(string.match(regex));
// -> ["123"]
从这个例子也可以看出来,选择分支是非贪婪的,即 p1 满足了,就不再去尝试匹配 p2 了。
匹配位置
除了匹配字符,正则表达式的一个重磅功能就是匹配位置,即开头、结尾和字符之间的位置。一些常用的表示方法如下
^
匹配开头,多行模式下匹配行开头$
匹配结尾,多行模式下匹配行结尾\b
匹配\w 和\W 的位置,自然就有包括\w 和^以及\w 和\$之间的位置\B
是\b
取反(?=p)
模式 p 前面的位置 positive lookahead(?!p)
上面的逻辑取反 negative lookahead
2019-5-30 更新,ES6 中新增了两个位置
- (?<=p) 模式 p 后面的位置 positive lookbehind
- (?<!p) 上面的逻辑取反 negative lookbehind
引用分组
被()
包裹起来的模式可以在正则表达式中和 JS 相关 API 中被引用,当被正则表达式引用时,使用\数字
表示,在被 JS 相关 API 引用时,使用$数字
表示,其中的数字
范围从 1 到 99。
下面通过几个例子展示一下具体的用法
var regex = /\d{4}(-|\/)\d{2}\1\d{2}/;
var string1 = "2016-07-18";
var string2 = "2016/07/18";
var string3 = "2016-07/18";
regex.test(string1); // -> true
regex.test(string2); // -> true
regex.test(string3); // -> false
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2016-07-18";
var result = string.replace(regex, "$2/$3/$1");
console.log(result); // -> 07/18/2016
元字符
在编写正则表达式时,遇到下面这 20 个字符,要记得转义
\ | /
() [] {}
+ - * =
. , : ! ?
^ $
JS API
在 JS 中可以通过如下 API 使用正则表达式完成查找、替换、验证等操作
- regex.test(string)
- regex.exec(string)
- string.search(regex)
- string.match(regex)
- string.split(regex)
- string.replace(regex, string/function)
其他有趣的点
如果要匹配任意字符,可以使用逻辑取反操作来完成,比如[\d\D]
/ [\s\S]
/ [\w\W]
/ [^]
如果要写一个什么都匹配不了的模式,可以这样:/.^/
即任意字符后面有个开头,这当然是不存在的