Regular Expression(正则表达式)

概述

参考:

记于 2023 年 2 月10 日:有了 ChatGPT,这正则表达式。。。我想。。。应该再也不用背了。。。。

Regular Expression(正则表达式,简称 RegEX 或 RegEXP) 是用于定义 Search Pattern(搜索模式) 的一系列字符串。这种 Pattern(模式) 通常被字符串搜索算法用于 find(查找) 字符串、或 find and replace(查找并替换) 字符串、或者验证输入内容。RegEX 是一种在 Theoretical Computer Science(理论计算机科学) 和 Formal Language(形式语言) 理论中发展起来的技术。

还有一个学名 Perl Compatible Regular Expressions(Perl 兼容的正则表达式,简称 PCRE),这用来表示 Perl 语言兼容的正则表达式。

用白话说,所谓的 正则表达式,就是用来通过一种称为 Pattern(模式) 的方式,筛选出长篇内容里的部分内容。其实就是一堆字符组合在一起形成一种行为,这个行为就是匹配字符行为。也可以勉强算编程语言的一种吧~

所以,这个世界在很多时候,把正则表达式这个概念,用 RegEX、RegEXP、Pattern 这几种单词表示。

RegEX 概念产生于 1950 年,美国数学家 斯蒂芬·科尔·克莱恩 正式定义了 Regular Language(正则表达式语言)。这个概念在 Unix 文本处理工具中得到了普遍使用,自 20 世纪 80 年代 以来,存在着不同的正则表达式书写语法,一种是 POSIX 标准,另一种是 Perl 语法。

正则表达式用于搜索引擎,字处理器和文本编辑器的搜索和替换对话框,sed 和 awk 等文本处理应用程序以及词法分析中。许多编程语言通过内置或库提供正则表达式功能。

正则表达式的符号参考

说明:

  • ... 表示任意字符串,并不是正则字符的组成部分

字符匹配

字符描述
.匹配除换行符之外的任意单个字符(不包含空行)。等价于 [^\n\r]
\w匹配字母、数字、下划线。等价于 [A-Za-z0-9_]

次数匹配模式:匹配该表达式前面的一个字符出现的次数

符号详解
*次数匹配,匹配 * 前面的一个字符重复出现任意(包括 0 次,即不出现前一个字符)次数,例:x是无数个 x,1是无数个 1
.*重复任意一个字符,即任意多个字符
^.*以任意多个字符串开头,.*尽可能多,有多少算多少,贪婪性
?? 前面字符出现 0 次或者 1 次的,即问一下这个字符有还是没有
+匹配 + 前的字符至少一次
{m}匹配前一个字符 m 次,例:grep “s\{3\} /home 匹配 sss 的内容
{m,n}匹配最少 m 次,最多 n 次,注意:这几种类型的匹配如果不在 egrep 中搜索需要在{前加\
{m,}匹配最少 m 次
{0,n}匹配最多 n 次

非打印字符匹配

符号描述
\cx匹配由 x 指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 ‘c’ 字符。
\f匹配一个换页符。等价于 \x0c 和 \cL。
\n匹配一个换行符。等价于 \x0a 和 \cJ。
\r匹配一个回车符。等价于 \x0d 和 \cM。
\s匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。注意 Unicode 正则表达式会匹配全角空格符。
\S匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\t匹配一个制表符。等价于 \x09 和 \cI。
\v匹配一个垂直制表符。等价于 \x0b 和 \cK。

锚点匹配:用于指定字符出现的位置

符号详解
^指定行首,^WORD 搜索一行开头以 WORD 字符开头的行的内容
$指定行尾,word$搜索一行最后以 word 结尾的内容
^$表示空白行,不是空格(^li$显示只有 li 的行)
\b匹配单词边界
\>指定词尾, “abc\>”表示所有包含以”abc”结尾的单词的行“
\<指定词首, “\<abc”表示所有包含以”abc”开头的单词的行“

括号表达式

符号详解
[abc][0-9][\.,/]匹配字符集合内的任意一个字符 a 或 b 或 c。[a-z]匹配所有小写字母,表示一个区间,[abc]找 a 或 b 或 c 可以写成[a-c]
[^abc]匹配不包含^后的任意字符 a 或 b 或 c,是对[abc]的取反,且与^含义不同
[\s\S]匹配所有。\s 匹配所有空白符。\S 匹配所有非空白符,包括换行
[[:space:]]匹配空白字符
[^[:space:]]匹配非空白字符

特殊符号

符号详解
\escape character(转义字符),让有特殊含义的字符脱掉马甲,不执行该特殊字符所代表的含义,如\.只表示小数点,不代表任意一个字符

元字符序列

| 元字符 |

示例
/a
a or b, pick one!表示“或”,即匹配其中任何一个,”bookdesk”将匹配”book”或”desk”
()小括号,可以将正则字符和元字符或表达式进行组合,”(book
-减号,用于指明字符范围, “[a-c]”将匹配包含 a、b 和 c 中任意一个字符的字符串
(..(..)..)(..)..\## 为任意数字,该字符表示匹配前面的第#个小括号组中的内容。正则表达式中的小括号”()“是代表分组的意思。 如果再其后面出现\1 则是代表引用第一个小括号中匹配的内容。注意:\1 必须与小括号配合使用
\# 例子(li)#\1 表示查找 li#li 这个内容
(li(chen))#\1\2 表示引用 lichen#lichenchen,注:括号顺序以左括号为准

子组结构

符号描述示例详解
(?!...)正向否定零宽断言/foo(?!bar)/
foobar foobaz子表达式不可在此后成功匹配的位置,不占用字符。
(?=)
表达式描述
(?=)正向预查。比如 Code(?=Sheep)能匹配 CodeSheep 中的 Code,但不能匹配 CodePig 中的 Code。
(?!)正向否定预查。比如 Code(?!Sheep)不能匹配 CodeSheep 中的 Code,但能匹配 CodePig 中的 Code。
(?<=)反向预查。比如(?<=Code)Sheep 能匹配 CodeSheep 中的 Sheep,但不能匹配 ReadSheep 中的 Sheep。
(?<!)反向否定预查。比如(?<!Code)Sheep 不能匹配 CodeSheep 中的 Sheep,但能匹配 ReadSheep 中的 Sheep。

基本和扩展正则表达式具体区别见下图,扩展中的元字符如果用在基本正则表达式中,需要在每个元字符前面加转义符

示例

空行

  • ^(\s*)\n

行尾的空字符串

  • \s+$

匹配所有 IPv4 地址

  • (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}

所有开头不是 # HELP 的行,以及行尾的换行符

  • ^(?!# HELP).*\n

从 hosts 文件中筛选出指定的域名

  • 去掉除所有 IP 地址
    • (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}
  • 方向匹配开头是 optical-admin 的所有行之后。即匹配开头不是 optical-admin 的行
    • ^(?!optical-admin).*\n

匹配所有汉字或空白字符

  • [\u4e00-\u9fa5 | \u00a0]

通配符

通配符含义实例
*匹配 0 或多个字符a*b a 与 b 之间可以有任意长度的任意字符, 也可以一个也没有, 如 aabcb, axyzb, a012b, ab。
?匹配任意一个字符a?b a 与 b 之间必须也只能有一个字符, 可以是任意字符, 如 aab, abb, acb, a0b。
[list]匹配 list 中的任意单一字符a[xyz]b a 与 b 之间必须也只能有一个字符, 但只能是 x 或 y 或 z, 如: axb, ayb, azb。
[!list]或[^list]匹配 除 list 中的任意单一字符a[!0-9]b a 与 b 之间必须也只能有一个字符, 但不能是阿拉伯数字, 如 axb, aab, a-b。
[c1-c2]匹配 c1-c2 中的任意单一字符 如:[0-9] [a-z]a[0-9]b 0 与 9 之间必须也只能有一个字符 如 a0b, a1b… a9b。
[!c1-c2]或[^c1-c2]匹配不在 c1-c2 的任意字符a[!0-9]b 如 acb adb
{string1,string2,…}匹配 sring1 或 string2 (或更多)其一字符串a{abc,xyz,123}b 列出 aabcb,axyzb,a123b

最后修改 June 6, 2024: systemd (1e9a8eb5)