社区文档构建进行中,欢迎编辑。社区答疑群(非官方):717421103,点点小课堂(腾讯会议):5696651544
帮助:正则表达式
正则表达式测试,本文作者batvbs
正则表达式
正则表达式可以用于搜索、查找、替换、验证、提取文本数据。
简介
毫无疑问,您已经使用过某些关于搜索、查找、替换的语法。
例如,您很可能使用过 *.txt 这样的搜索语法,搜索文件夹里的文本文档。正则语法 .*\.txt
? 通配符匹配 0 个或 1 个字符(搜索语法) * 通配符匹配 零个 或 多个 字符(搜索语法)
正则表达式的语法与一般的搜索语法不同,也更为强大。
比如,我们可以使用 正则表达式 1[0-9]{10} 匹配电话号码。
本文所有关于正则表达式的语法符号都是英文符号,请注意你的输入法
基础
正则表达式的基础语法
元素
元素是搜索条件的最小单位,普通字符都是元素。
例如,正则表达式 12345 包含五个元素, 1 2 3 4 5
- 普通字符:普通字符按照字面意义进行匹配,例如元素 a 将匹配到文本中的 a 字符,包含三个元素的正则表达式 abc 将匹配到文本中的 abc
如果一个正则表达式里 只有普通字符,那么它的匹配效果与搜索语法一致。
- 元字符:元字符具有特殊的含义,类似于搜索语法里的通配符,这里列出部分常用的
. 匹配一个任意字符(不含换行符) \d 匹配一个数字字符,等同 [0-9] \w 匹配一个字母或数字或下划线,等同 [0-9a-zA-Z_] \n 匹配一个换行符
量词
量词决定元素的匹配次数,仅影响前面的一个元素。
- ? 匹配前面的 元素 零次或一次。(使用 .? 等效搜索语法 ? )
- * 匹配前面的 元素 零次或多次。(使用 .* 等效搜索语法 * )
- + 匹配前面的 元素 一次或多次。
可以指定匹配次数。
- {n} 匹配前面的 元素 n 次。
- {n,} 匹配前面的 元素 至少 n 次。(尽可能匹配更多内容)
- {n,m} 匹配前面的 元素 至少 n 次且不超过 m 次。
默认 尽可能匹配更多内容,在量词后再加一个 ? 则尽可能匹配更少内容。
示例 ?? *? +? {n,m}?
例如,正则表达式 12?45 ,包含四个元素,1 2 4 5 ? 前面的元素是 2 ? 匹配前面的 元素 零次或一次。 所以,正则表达式 12?45 只能匹配 145 或 1245
字符范围
字符范围整体作为一个元素,可以使用量词。
- [ ] 匹配一个 括号内的任意字符。例如 [abc] 匹配字符 a 或 b 或 c
- [^ ] 匹配一个 不在括号内的任意字符。例如 [^abc] 匹配 a b c 以外的任意字符
可以使用 - 符号缩略顺序字符范围。例如 [abcd] 可以缩略为 [a-d]
比较常用的缩略有 [0-9] [a-z] [A-Z]
例如,正则表达式 1[234]5 包含三个元素 1 [234] 5 [234] 将被视为一个元素,可以使用 量词 所以,正则表达式式 1[234]5 只能匹配 125 或 135 或 145 如果我们想匹配一个四位数字,使用 正则表达式 [0123456789]{4} 或 [0-9]{4}
边界
边界确定匹配范围。
- ^ 匹配文本开头。
- $ 匹配文本结尾。
- \b 匹配单词边界。等同 ((?!\w)|(?<!\w))
- \B 匹配非单词边界。
例如,正则表达式 ^123$ 仅能匹配文本 123 里的 123 ,而不能匹配文本 12345 里的 123
转义
转义用于匹配特殊字符,在字符前使用 \ 转义
需要转义的语法符号
- 大中小括号 ( ) [ ] { }
- 量词 * + ?
- 边界 ^ $
- 点 或 自 . | \
- 字符范围 [ ] - ^ \
在字符范围里, - 需要转义。其他语法符号不生效,可选不转义
- wiki函数 | { } =
在wiki函数里,需要用模板对这四个符号进行替换,否则会解析错误,参见#转义(wiki)
例如, 匹配 * 这个字符,使用 \* 匹配 \ 这个字符,使用 \\ 希望注意的是,对无需转义的字符进行转义,可能导致错误
元字符
元字符,即预设的一些常用字符范围与特殊符号。
元字符 | 等同 | 字符范围 |
---|---|---|
. | [^\n] | 任意字符(不含换行符) |
\d | [0-9] | 数字 |
\D | [^0-9] | 非数字 |
\w | [0-9a-zA-Z_] | 字母、数字、下划线 |
\W | [^0-9a-zA-Z_] | 非字母、非数字、非下划线 |
\s | [\f\n\r\t\v ] | 任何空白字符,包括空格、制表符、换页符 |
\S | [^\f\n\r\t\v ] | 任何非空白字符 |
- | ||
\n | 换行符,等价于 \x0a 和 \cJ | |
\r | 回车符,等价于 \x0d 和 \cM | |
\t | 制表符,等价于 \x09 和 \cI | |
\v | 垂直制表符等,等价于 \x0b 和 \cK | |
\f | 换页符,等价于 \x0c 和 \cL | |
- | ||
\xn | 由 n 指明的字符编码, n 为十六进制ASCII编码。例如 \x41 匹配 A | |
\cX | 由 X 指明的控制字符,x为大小写字母。例如 \cL 匹配 换页符 | |
\un | 由 n 指明的字符编码, n 为十六进制Unicode编码。例如 \u6b63 匹配 正 |
嵌套
对多个正则表达式进行 组合、嵌套,使用子表达式的匹配结果
或
或,用于同时匹配多个正则表达式。
- | 分隔多个正则表达式
例如,正则表达式 win7|win8|win10 ,可以匹配 win7 或 win8 或 win10
子表达式
将正则表达式用括号括起来,整体作为一个元素,可以使用量词。
- ( ) 用于匹配一个子表达式,可引用匹配结果
- (?: ) 用于匹配一个子表达式,无法引用
例如,正则表达式 win(7|8|10) 可以匹配 win7 或 win8 或 win10 子表达式可以使用量词,如 win(10|11)? 可以匹配 win 或 win10 或 win11
边界表达式
边界表达式仅用于自定义边界,不计入匹配内容,也不可引用。
语法 | 定义 | 举例 |
---|---|---|
正则(?=正则) | 右侧肯定边界 | win(?=8|10) 能匹配 win8 或 win10 里的 win 但不能匹配 win7 或 win 里的 win ,因为边界不匹配 |
正则(?!正则) | 右侧否定边界 | win(?!8|10) 不能匹配 win8 或 win10 里的 win 但可以匹配 win7 或 win 里的 win ,因为边界不匹配 |
(?<=正则)正则 | 左侧肯定边界 | (?<=8|10)win 能匹配 8win 或 10win 里的 win 但不能匹配 7win 或 win 里的 win ,因为边界不匹配 |
(?<!正则)正则 | 左侧否定边界 | (?<!8|10)win 不能匹配 8win 或 10win 里的 win 但可以匹配 7win 或 win 里的 win ,因为边界不匹配 |
需要注意的是,边界是一个确定的位置(右侧边界为匹配结果开头,左侧边界为匹配结果结尾)
边界表达式的额外用法: 正则表达式仅 字符范围 和 边界 可以否定匹配,能否实现 否定匹配 某个单词 或正则表达式? 我们可以使用 ^(?!.*(表达式)).* 来变相实现, 例如 ^(?!.*win.*) 可以匹配任何不含 win 的文本 看不懂?我们拆开看 .*win.* 匹配任何包含 win 的文本(尽可能匹配更多内容) (?!.*win.*) 将任何不包含 win 的文本开头标记为边界 ^(?!.*win.*) 左侧边界是 文本开头,右侧边界是 任何不包含 win 的文本开头 - 当文本中含有win时,因右侧边界不符合 无匹配; - 否则,进行匹配(匹配位置文本开头,匹配内容为空) 因为右侧边界是匹配结果开头,也就是文本开头,所以我们可以加上 .* 以匹配全文 win右侧的内容不影响匹配,删掉 .* ,于是我们得到了 ^(?!.*(表达式)).*
引用
引用子表达式的匹配结果作为一个元素,可以使用量词。
\编号 子表达式的匹配结果
子表达式的编号,按照左括号 ( 的位置,从左到右排序,十进制数字。完整表达式的编号为 &
示例,一个多重嵌套的正则表达式 a((b)c)(d){2} \0 对应表达式 a((b)c)(d){2} 的匹配结果 abcdd \1 对应表达式 ((b)c) 的匹配结果 bc \2 对应表达式 (b) 的匹配结果 b \3 对应表达式 (d){2} 的匹配结果 dd
只能引用编号不超过两位数的子表达式。
子表达式可以使用 (?: ) 标记放弃引用,不计入编号
引用最常见的应用之一,查找文本中两个相同 的 相邻单词。以下面的句子为例: is is! the cost of of ging up? 使用正则表达式 (\w+) \1 ,可以匹配到句子里的连续重复单词 is is 与 of of
语法优先级
相同优先级的,从左到右运算。不同优先级的,先高后低运算。
语法 | 描述 |
\ | 转义符 |
( ) (?: ) (?= ) [ ] | 圆括号和方括号 |
* + ? {n} {n,} {n,m} | 量词 |
^ $ 元字符 任何字符 | 字符,元字符,边界 |
| | 或 |
或 的运算符优先级最低,使得 m|food 匹配 m 或 food 若要匹配 mood 或 food ,请使用括号创建子表达式 (m|f)ood
使用(wiki)
在wiki里,正则表达式的写法为 /正则表达式/模式
模式
模式是额外的匹配规则,不属于正则表达式。
- i :不区分大小写,A 和 a 没有区别(默认区分大小写)
- g : 全局匹配,查找所有的匹配项(默认只查找一个匹配项)
- m : 每行匹配,使边界 ^ 和 $ 匹配每一行的开头和结尾(默认匹配全文的开头和结尾)
- s :包含换行符,使元字符 . 匹配任何字符,包括换行符(默认 . 不匹配换行符\n )
模式可以留空,也可以同时使用多个,示例 /^abc/gm
匹配字符 / 不需要转义,示例 /// wiki里 \/ 不会报错且可正常匹配 / ,但其他语言不行!
转义(wiki)
部分正则表达式符号在wiki函数里有特殊用途,需要替换为模板,模板内容为符号,以避免解析错误。
已预设以下模板,如果没有可自行新建
/正则表达式/ 不支持 <nowiki> 标签,不可用于转义。
查找
查找指定内容,如果有匹配,执行代码1 如果没有匹配,执行代码2
{{#rmatch:源字符串|/正则表达式/模式|匹配|不匹配}}
{{#rmatch:Windows7|/do/|找到啦|没找到}} | 存在do | 找到啦 |
{{#rmatch:Windows7|/re/|找到啦|没找到}} | 不存在re | 没找到 |
{{#rmatch:win7 WIN8 win11|/win/i|找到$0|}} | 可引用 | 找到win |
替换
查找指定内容,将 所有 匹配结果 替换为 指定文本,详见 #rreplace
{{#replace:源字符串|搜索文本|替换文本}} {{#rreplace:源字符串|/正则表达式/模式|替换文本}} 注意函数名称多一个r
{{#rreplace:win7 WIN8 win11|/win/|-}} | 替换所有匹配结果 | -7 WIN8 -11 |
{{#rreplace:win7 WIN8 win11|/win/i|-}} | 模式i不区分大小写 | -7 -8 -11 |
{{#rreplace:win7 WIN8 win11|/or/i|-}} | 没有匹配,输出原文 | win7 WIN8 win11 |
引用
可以引用正则表达式的匹配结果
使用 $0 或 ${0} 或 \0 引用 整个表达式的匹配结果 使用 $n 或 ${n} 或 \n 引用 第n个子表达式的匹配结果
{{#rmatch:win7 WIN8 win11|/win/i|找到$0|}} | 引用 整个表达式的匹配结果 | 找到win |
{{#rreplace:win7 WIN8 win11|/win/i|-$0-}} | 引用 整个表达式的匹配结果 | -win-7 -WIN-8 -win-11 |
{{#rreplace:abcdd|/a((b)c)(d){2}/|$0-$1-\2-${3}666}} | 引用 子表达式的匹配结果 | abcdd-bc-b-d666 |