概述

正则表达式(Regular Expression,Regex)是用于匹配字符串中字符组合的模式。它由一系列字符和特殊符号组成,可以高效地执行查找、替换、检查数据格式等多种文本处理任务。正则表达式的概念最初由数学家斯蒂芬·克莱尼在 20 世纪 50 年代提出,最早用于理论计算机科学和形式语言理论中。

几乎所有现代编程语言都支持正则表达式,包括 Python、JavaScript、Java、C#等。此外,许多文本编辑器和开发环境(如 VSCode、Sublime Text)以及命令行工具(如 grep)也广泛应用正则表达式进行文本搜索和编辑。

基本概念

  • 字面字符:指在表达式中表示它们自身字面意义的字符,例如 a1B
  • 特殊字符:在正则表达式中用来表示控制或通配符作用的字符,如 *(匹配前一个字符 0 次或多次)。

元字符

元字符是构成正则表达式逻辑的基础,具有特殊的匹配含义:

元字符描述
.句号匹配任意单个字符除了换行符。
[ ]字符种类。匹配方括号内的任意字符。
[^ ]否定的字符种类。匹配除了方括号里的任意字符
*匹配 >=0 个重复的在 * 号之前的字符。
+匹配 >=1 个重复的 + 号前的字符。
?标记 ? 之前的字符为可选。
{n,m}匹配 num 个大括号之前的字符或字符集 (n num m)。
(xyz)字符集,匹配与 xyz 完全相等的字符串。
``
\转义字符,用于匹配一些保留的字符 `[ ] ( ) { } . * + ? ^ $ \
^从开始行开始匹配。
$从末端开始匹配。

字符类

字符类允许匹配指定集合中的字符,常见的标准字符类和自定义字符类如下:

简写描述
.除换行符外的所有字符
\w匹配所有字母数字,等同于 [a-zA-Z0-9_]
\W匹配所有非字母数字,即符号,等同于: [^\w]
\d匹配数字: [0-9]
\D匹配非数字: [^\d]
\s匹配所有空格字符,等同于: [\t\n\f\r\p{Z}]
\S匹配所有非空格字符: [^\s]
\f匹配一个换页符
\n匹配一个换行符
\r匹配一个回车符
\t匹配一个制表符
\v匹配一个垂直制表符
\p匹配 CR/LF(等同于 \r\n),用来匹配 DOS 行终止符

自定义字符类

示例描述
[a-z]匹配任何小写字母
[A-Z]匹配任何大写字母
[0-9]匹配任何数字
[aeiou]匹配所有小写元音字母
[^0-9]匹配任何不是数字的字符(方括号内的 ^ 表示非)

位置匹配

位置匹配用于确定字符匹配的具体位置,如行首或行尾等:

锚点字符描述
^不仅表示行的开始,也可在多行模式中匹配每一行的开始
$表示行的结束或字符串的结束,同样在多行模式中可匹配每一行的结束

量词和分组

量词和分组是正则表达式中非常强大的功能,它们让我们可以定义复杂的模式,进行精确的文本匹配和操作。这部分内容也可以用表格形式进行更清晰的展示。

量词

量词用于指定一个元素出现的次数,是正则表达式中控制匹配频度的关键工具。

量词描述
*匹配前一个元素 0 次或多次。
+匹配前一个元素 1 次或多次。
?匹配前一个元素 0 次或 1 次。
{n}匹配前一个元素恰好 n 次。
{n,}匹配前一个元素至少 n 次。
{n,m}匹配前一个元素至少 n 次,但不超过 m 次。

贪婪与非贪婪量词

量词默认为贪婪模式,尽可能多地匹配字符。通过添加 ? 后缀,量词变为非贪婪模式,尽可能少地匹配字符。

类型示例描述
贪婪匹配a.*baxxxbxxxb 中匹配从第一个 a 到最后一个 b 的整段文本。
非贪婪匹配a.*?baxxxbxxxb 中匹配最短的,以 a 开始,以 b 结束的文本。

分组和引用

分组允许将正则表达式中的部分模式括起来,作为一个整体进行操作,这对于提取信息、构建复杂模式或进行条件匹配非常有用。

捕获分组与非捕获分组

类型示例描述
捕获分组(abc)匹配 abc,并捕获匹配的文本,以供后续引用。
非捕获分组(?:abc)匹配 abc,但不捕获匹配的文本,仅用于匹配操作。

后向引用

后向引用让我们能够引用正则表达式中先前定义的捕获组,这对于匹配重复的文本或验证两部分内容相同非常有用。

示例描述
(\b\w+)\s+\1匹配一个由单词、空格和相同单词构成的模式,如 word word

高级匹配

断言

断言是正则表达式中的一个高级特性,允许进行条件匹配,即只有在满足特定条件的情况下才进行匹配。

符号描述
?=正先行断言 - 存在
?!负先行断言 - 排除
?<=正后发断言 - 存在
?<!负后发断言 - 排除

前向肯定断言 (?=)

  • 前向肯定断言允许你指定一个子模式必须出现在某个匹配之后,但不会成为匹配结果的一部分。例如,a(?=b) 会匹配前面有 a 且后面紧跟 b 的位置,但不会返回 b

前向否定断言 (?!)

  • 前向否定断言用来指定一个子模式必须不出现在某个匹配之后。例如,a(?!b) 会匹配所有后面不跟 ba

后向断言

  • 在支持的语言中(如 JavaScript),后向断言允许你指定一个子模式必须出现在某个匹配之前。如 (?<=b)a 表示 a 前面必须有 b

标志/模式修饰符

标志或模式修饰符用于改变正则表达式的匹配行为。

标志描述
i忽略大小写。
g全局搜索。
m多行修饰符:锚点元字符 ^ $ 工作范围在每行的起始。

大小写不敏感 (i)

  • 使用此标志后,匹配时将不区分大小写。例如,正则表达式 /abc/i 将匹配 AbcaBcabc 等。

多行模式 (m)

  • 在多行模式下,^$ 不仅匹配输入字符串的开始和结束位置,也匹配行的开始和结束。

点号包含换行 (s)

  • 通常,. 不匹配换行符。使用此标志后,. 也将匹配换行符。

参考实例