正则常用规则的备注

2020-12-29

< view all posts

这篇文章主要是对正则的常用规则中一些容易模糊不清的地方进行备注,例如\w的精确判断方式,在[ ]中^和-符号的含义与其位置的关系等。

这篇文章并没有包含所有的正则规则,目的也并非对涉及的规则作详细的解释,因此建议和正则文档或教程结合阅读,作为补充。另外,后面的一篇文章《正则的执行方式》对于理解复杂的正则也会有所帮助。

文中用到的主要参考来自regular-expressions.info正则表达式30分钟入门教程微软的正则表达式参考文档

字符类

Use To match any character Remarks
[set] In that set [ ]内被正则占用的语言元素 如* ?等可以不需要转义直接写
[^set] Not in that set ^写在[ ]的开头时表示匹配整个集合的反向结果。写在[ ]的中间时则表示匹配^这个字符本身。
[a–z] In the a-z range - 写在[ ]的开头或结尾时表示匹配 - 字符本身。尽管一些语言可以通过 - 两端的符号推测它的含义,但是不建议在需要匹配 - 本身时把它直接写在中间。如果要写在中间,应该加上\进行转义。
[^a–z] Not in the a-z range
. Any except \n (new line)
\char Escaped special character 被正则占用的语言元素包括 . ^ $ * + ? { } [ ] ( ) \ |    此外还可以使用Unicode编码来表示字符,如 \u000A
\w Word character 大多数语言中等价于[A-Za-z0-9_],即匹配数字、字母和下划线
\W Non-word character 在正则中 \大写字母 一般是 \小写字母 的反向结果,即\W等价于[^\w]
\d Decimal digit 等价于[0-9]
\D Not a decimal digit 等价于[^\d]
\s White-space character 大多数语言中等价于[ \t\r\n\f],即匹配空格、制表符、换行符和分页符
\S Non-white-space char 等价于[^\s]

注:在[ ]内使用否定表达时需要格外注意,例如[\D\S]和[^\d\s]并不等价:[\D\S]匹配(不是数字)或者(不是空白字符)的任意字符,因为一个字符不可能同时为数字和空白字符,所以[\D\S]实际上会匹配所有字符。而[^\d\s]匹配不是(数字或者空白字符)的任意字符,所以它会匹配到字母和各种特殊符号。

定位点

Use To specify position Remarks
^ At start of string or line 匹配字符串的起始位置;在多行模式下匹配行的起始位置
\A At start of string 始终匹配字符串的起始位置(不受多行模式影响)
\z At end of string 始终匹配字符串的结束位置(不受多行模式影响);如果字符串结尾是\n,可以匹配这个\n
\Z At end (or before \n at end) of string 始终匹配字符串的结束位置(不受多行模式影响);如果字符串结尾是\n,不匹配最后的一个\n
$ At end (or before \n at end) of string or line 匹配字符串的结束位置;在多行模式下匹配行的结束位置;如果字符串或行的结尾是\n,不匹配最后的一个\n
\G Where previous match ended 匹配前一个匹配的结束位置,例如\G\(\d\)可匹配到"(1)(3)[7](9)" 中的 "(1)"和"(3)"
\b On word boundary 匹配以下三种位置:(1)字符串的起始位置,且对应的起始字符是\w;(2)字符串的结束位置,且对应的结束字符字符是\w;(3)字符串的中间位置,且这个位置的左边和右边至少有一个字符不是\w
\B Not on word boundary 匹配所有不是\b的位置

注:表格中是对\b的精确定义,关于它的判断流程,在后面一篇文章《正则的执行方式》中有一个详细的例子(含定位点的正则)做了介绍。实际使用中一般把\b理解成单词的分界位置即可。

数量词

Greedy Lazy Matches Remarks
* *? 0 or more times
+ +? 1 or more times
? ?? 0 or 1 time
{n} {n}? Exactly n times {n}的贪婪和懒惰写法效果是一样的
{n,} {n,}? At least n times
{n,m} {n,m}? From n to m times

注:数量词修饰它前面的一个正则规则。一个正则规则是指:一个字符(字面规则)、一个分组构造或一个字符类。

分组构造

Use To define Remarks
(exp) Indexed group 组号的分配规则:整个正则构成编号为0的组,之后从1开始到n的编号分配给n个未命名组,命名组的编号从n+1开始。同级的组编号从左向右递增,以左括号的位置为准
(?<name>exp) Named group
(?:exp) Noncapturing group 非捕获组不影响正则的匹配,只是不会被分配编号
(?=exp) Zero-width positive lookahead 零宽度断言都是非捕获的,不会被分配编号
(?!exp) Zero-width negative lookahead
(?<=exp) Zero-width positive lookbehind 回顾后发断言的符号比先行预测断言的符号多一个<
(?<!exp) Zero-width negative lookbehind
(?>exp) Non-backtracking (greedy) 原子组是非捕获的,不会被分配编号

反向引用构造

Use To match Remarks
\n Indexed group 例如 (\w)\1 匹配 "seek" 中的 "ee"
\k<name> Named group 例如 (?<char>\w)\k<char> 匹配 "seek" 中的 "ee"

替换构造

Use To match Remarks
a|b Either a or b | 在所有符号中的优先级是最低的,所以一般会把可选项放到分组构造( )里面
(?(exp)yes|no) yes if exp is matched no if exp isn't matched 如果由 expression 指定的正则表达式匹配,则匹配 yes ;否则,匹配 no
(?(name)yes|no) yes if name is matched no if name isn't matched 如果 name (已命名或已编号的捕获组)匹配,则匹配 yes;否则,匹配 no。