社区文档构建进行中,欢迎编辑。社区答疑群(非官方):717421103,点点小课堂(腾讯会议):5696651544

全站通知:

帮助:正则表达式

来自WIKI实验室WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

正则表达式测试,本文作者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