学习正则表达式
正则表达式不少地方都会用到,比如检查某个字符串是否符合指定的格式、提取出目标文本中所需的字符串内容以及批量替换目标字符串,所以还是有必要专门学习下的。
最简单表达式就是字符串内容本身,比如
aabbcc
可以匹配aabbcc
,问题是这样来一个字符串就得重新写一个表达式,肯定是没法减少工作量的。所以需要用到正则里的关键字,下面就罗列下这些关键字。
1 单个字符的匹配规则
常用的有三条规则
.
能匹配任意字符
[]
可以匹配中括号中的任意一个字符,比如
[0,1] 表示只能匹配0或者1
[0-7] 表示能匹配0-7范围内的整数
[a-e] 表示能匹配a-e范围内的小写字母
[a-e0-7] 表示能匹配a-e范围内的小写字母或者0-7范围内的整数
数字元字符,比如
\d 表示匹配任意的数字,等价于 [0-9]
\w 表示匹配任意一个数字或字母(大小写都行)或下划线
\s 表示匹配空白字符
如果字母改为大写,那就是取反的意思,比如
\W 表示匹配数字、字母及下划线以外的字符
2 匹配次数
用于指定表达式的重复匹配,目前有两种规则
*
表示匹配0次或更多次,+
表示匹配1次或更多次,?
表示匹配0次或1次
{m,n}
表示匹配 m-n 次,比如
{2} 表示匹配 2 次
{2,5} 表示匹配 2-5 次
{2,} 表示匹配 2 次及以上
注意,其中*
、+
、和 {m,}
都具备贪婪匹配的特性,所谓的贪婪匹配,指的是尽可能匹配更多字符,而 ?
还有禁止贪婪匹配的作用
举个例子,对于 abcbcbc
,如果用 a.+bc
,会匹配到 abcbcbc
,如果用 a.+?bc
,会匹配到 abcbc
3 匹配一组字符
前面两部分规则只能让我们进行单个字符的重复匹配,但是有一些需求,光靠这些不好实现,比如希望以 (至少一位字母 + 至少一位数字)为基本单位,然后目标字符串必须由这种单位的1次或多次重复组成。
(表达式)
,会尝试去匹配符合表达式的字符串,又被称为子表达式
借助这个特性,就能写出符合之前要求的表达式,如下。
([a-zA-Z]+\d+)+
4 匹配特定位置
了解上面两部分规则后,就可以写一些表达式来匹配整个字符串了,但如果对匹配字符串有位置上的要求,比如前后字符串必须符合其它的规则,就得了解如何匹配位置,有两种
^
表示匹配开头,$
表示匹配末尾
需要注意的是,如果 ^
用在 []
中,含义会变成取非,比如 [^1]
就表示匹配除 1 以外的字符
表达式1(?=表达式2)
表示去匹配表达式 1,但是后面的字符串必须符合表达式 2
(?<=表达式1)表达式2
表示去匹配表达式 2,但是前面的字符串必须符合表达式 1
5 回溯引用
如果希望去引用前面某个表达式的匹配结果,比如说去匹配一组重复的单词,又比如,我在写作时,为了省事直接把链接复制进去,后来发现一长串的看起来不美观,就希望将其替换成符合 markdown 规范的链接格式。
要使用回溯引用,必须使用子表达式 ()
把表达式整个包括起来,规则如下
(表达式1)其它表达式\1
表示要匹配成功,目标字符串必须符合表达式1其它表达式表达式1
,且两个表达式1
匹配的内容必须完全一致如果用到了多个子表达式,那么 \n 则代表重复第 n 个子表达式的匹配结果
6 匹配正则表达式占用的字符
可以看到,为了实现语义,正则表达式占用了一些字符,如果试图去匹配这些字符本身,比如 .
和[
这些,就得用到转义字符 \
比如要匹配.
,得用 \.
比如要匹配[
,得用 \[