Skip to content

Latest commit

 

History

History
139 lines (109 loc) · 6.71 KB

regex.md

File metadata and controls

139 lines (109 loc) · 6.71 KB

正则表达式

正则表达式的标准并不统一,此处为大多数标准都支持的,具体还得查看使用的正则引擎的文档

注意:Vim 的正则语法除了^$.*[]外其他元字符在默认模式下都得加\

零宽断言

符号 含义 备注
^ 文首或行首 (all)
$ 文末或行尾 (all)
\b 单词边界 (+cpp+go+posix)
\B 非单词边界 (+cpp+go+posix)
< 单词左边界 (+vim+posix)
> 单词右边界 (+vim+posix)
(?=pattern) 顺序预查 (+cpp)
(?!pattern) 顺序否定预查 (+cpp)
(pattern)@= 顺序预查 (+vim)
(pattern)@! 顺序否定预查 (+vim)
(pattern)@<= 逆序预查 (+vim)
(pattern)@<! 逆序否定预查 (+vim)

实体模式

符号 含义 备注
. 匹配除\n外任意字符 (all)
[] 匹配 class 中表示的字符 (all)
[^ ] 匹配非 class 中表示的字符 (all)
* 匹配前一个字符 0 - ∞ 次 (all)
*? 懒惰匹配版* (+cpp+go)
{-} 懒惰匹配版* (+vim)
+ 匹配前一个字符 1 - ∞ 次 (all)
+? 懒惰匹配版+ (+cpp+go)
? 匹配前一个字符 0 或 1 次 (all)
?? 懒惰匹配版? (+cpp+go)
{n} 匹配前一个字符 n 次 (all)
{n,} 匹配前一个字符至少 n 次 (all)
{n,m} 匹配前一个字符 n-m 次 (all)
{n}? 匹配前一个字符 n 次 (+cpp+go)
{n,}? 匹配前一个字符至少 n 次 (+cpp+go)
{n,m}? 匹配前一个字符 n-m 次 (+cpp+go)
x|y 匹配左或右的模式,左侧优先 (all)
(rgx) 编号匹配组,编号即左括号出现的顺序 (all)
(?:rgx) 非匹配组 (+cpp+go)
(?P<name>rgx) 具名编号匹配组,名字即 name (+go)
%(rgx) 非匹配组 (+vim)
\1, ..., \N 反向引用,替换为第 N 个匹配组 (+cpp+vim+posix)

字符类

ASCII 字符类 内容
[:alnum:] 字母+数字
[:alpha:] 字母
[:upper:] 大写字母
[:lower:] 小写字母
[:digit:] 数字
[:xdigit:] 十六进制数字
[:punct:] 符号
[:blank:] \t
[:space:] \t \n \r \v \f
[:cntrl:] \x00-\x1F\x7F
[:graph:] [[:alnum:][:punct:]]
[:print:] [[:alnum:][:punct:] ]
Unicode 字符类 内容
\pL 字母、汉字等
\pN 数字
\pM 标记
\pP 标点符号
\pS 特殊符号
\pZ 分隔符

转义字符

转义字符 含义 备注
\d \D [[:digit:]]、[^[:digit:]] (+cpp+vim+posix)
\s \S [[:space:]]、[^[:space:]] (+cpp+vim+posix)
\w \W [[:alnum:]_]、[^[:alnum:]_] (+cpp+vim+posix),posix 为 unicode
\n \r \t \v \f (+cpp+vim)
\0 \xhh \uhhhh null 字符、ansi、unicode (+cpp)
\a \b \e 警报、退格、escape
\x \X [[:xdigit:]]、[^[:xdigit:]] (+vim)
\l \L [[:lower:]]、[^[:lower:]] (+vim)
\u \U [[:upper:]]、[^[:upper:]] (+vim)
\a \A [[:alpha:]]、[^[:alpah:]] (+vim)

匹配技巧

  • [^y]x*[^y]:企图避免在连续 x 前后马上接 y(错误)。考虑匹配yxxxy时,x*匹配x,前一个[^y]匹配第一个x,后一个[^y]匹配第三个x, 因为x*的连续匹配提前结束,故应该这样写 regex:[^yx]x*[^yx]

  • [^x]*y:企图避免在 y 前面出现 x(错误)。因为[^x]*可以匹配 nothing,即什么也不用匹配也算作匹配成功。 故应该这样写 regex:^[^x]*y

  • [^x]y:企图避免在 y 前面相邻位置接 x(错误)。因为未考虑 y 前面"没有字符"的情况。 故应该这样写 regex:([^x]|^)y

  • 利用逆向思维,将不应该在某位置出现什么,转换为应该在某位置出现什么,注意该位置是否可以为空

性能优化

  • Character Classes:替换掉.转而用更小的范围,即使是[^ ]也会有大幅提升
  • 适当使用零宽断言