正则表达式[学习笔记分享]

正则表达式

参考资料

GPT-5 by https://aizex.cn/cw4Y6M

Kimi-K2 by https://www.kimi.com/

DeepSeek-V3.1 by https://yuanbao.tencent.com

正则表达式(Regular Expression, 简称 Regex)是一种用模式来描述文本结构的语言,常用于匹配、查找、验证或替换文本

比如,邮箱往往符合 <数字或字母>@<域名> 的结构,这个结果可用正则表达式描述为:

[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}

其匹配原理通常是:

  1. 从字符串的第一个字符开始尝试匹配
  2. 如果某个部分不匹配,就回溯到上个可能的匹配点再尝试
  3. 最后返回“匹配成功/失败”的结果,或返回所有匹配到的片段

正则表达式的标准语法是大体相通的,但是在不同编程语言下可能存在细微的区别

基础语法

元字符与普通字符

在正则表达式的语法中,字符分为普通字符与元字符

  • 普通字符:代表它自己。例如 a 就匹配字符串中的字母 a
  • 元字符:具有特殊含义

常见的元字符有

符号 含义 示例
句号 . 匹配任意一个字符(除开换行符号) a.c 匹配 abcaxc
[] 匹配方括号内任一字符
[^] 匹配不在方括号内的字符
^ 匹配字符串/行开头 ^abc 匹配以 abc 开头的文本
$ 匹配字符串/行结尾 abc$ 匹配以 abc 结尾的文本
\d 匹配任意数字(部分编程语言可能匹配其他语言的数字字符)
\D 匹配任意非数字
\w 匹配任意字母、数字、下划线

量词与重复

量词就是告诉正则“这个部分要重复多少次

量词 含义 示例 匹配结果举例
* 任意次 ba* b ba baaa
+ 1 次及以上 ba+ ba baaa
? 0 次或 1 次 ba? b ba
{n,m} 重复 nm ba{2,4} baa baaa baaa
{n} 指定重复 n

语法上,量词控制的范围是前一个元素

{2,} 表示至少重复两次

匹配的贪婪与惰性

正则表达式下,可能出现多个匹配片段相互重叠、嵌套的问题,比如:

<.*>

如上表达式匹配所有尖括号包含部分,如果遇到以下的字符串

<abc><def>

注意到,<abc> 符号条件、<abc><def> 同样符合条件。这时,是否要去除重叠依赖于具体场景

正则表达式提供了是否去除重叠的选项,贪婪匹配和惰性匹配——

  • 贪婪(greedy)匹配会为片段尽可能多地匹配字符,直到最后一个。对于如上的示例字符串,返回 <abc><def>

  • 惰性匹配会尽可能少地匹配字符,生成更多短小的匹配片段。对于如上的示例字符串,返回 <abc><def>

其中量词默认是贪婪匹配。在量词后面加 ? 启用惰性匹配,如 *?

分组与引用

分组、捕获、引用

之前的语法中,元字符只能匹配单个字符及其复制,如 ab+ 只重复 b。而有时候我们需要匹配词语,这就是分组的作用——(ab)+ 按照整个 ab 做匹配(匹配 ab, abab, ababab

当你希望把一个整体结构看作一个元素时,就需要用 (),它的主要作用有:

  • 控制量词的作用范围
  • 把匹配的部分保存起来,后续的匹配可以直接引用保存片段

正则中的每一对括号,默认都会有一个从 1 开始的编号

(\d{3})-(\d{4})

上述表达式匹配 123-4567 时,第一组 \1 匹配 123,第二组\2 匹配 4567,且可以通过编号调用这些内容

(?: ) 是非捕获组,只分组,不保存结果

Python 中,可以使用自定义的名字代替编号 (?P<name>)

正则使用被分组捕获的元素,就是 引用

(\w+)\s+\1

(\w+) 匹配一个单词(即多个连着的字母),且自动被编号保存;\s 匹配空格;\1 则匹配编号为 1 的内容,即 (\w+) 匹配的单词

如,cat cat 会被匹配,cat dog 不会被匹配

用于匹配一个位置,如第 x 字符与第 x+1 字符之间的位置,而不是具体的字符。它在匹配时不“吃掉”字符

(?...)

(为方便理解,本章节使用 <exp> 代表表达式、| 代表位置而非字符)

在判断位置时,往往需要以某字符片段为基准,可以匹配或不匹配正则表达式 <exp> 代表的片段;可以在该片段前的位置 |<exp>,也可以在该片段后的位置 <exp>|。根据以上提到的两个选项,可以分出四种零宽断言类型

  • (?=<exp>) 正向前查找:匹配一个位置,这个位置右侧的内容必须能匹配表达式 <exp>
  • (?!<exp>) 负向前查找:匹配一个位置,这个位置右侧的内容必须不能匹配表达式 <exp>
  • (?<=<exp>) 正向后查找:匹配一个位置,这个位置左侧的内容必须能匹配表达式 <exp>
  • (?<!<exp>) 负向后查找

记忆方法

出现 ! 代表为负向查找,要求不能匹配表达式 <exp>

出现 < 代表向后查找,检测这个位置左侧的内容

示例:

user@example.com

对于如上文本,有:

  • \w+(?=@) 匹配 user(?=@) 查找到位置为 @ 的左侧 user|@\w+ 在零宽断言的左边,匹配到 user
  • (?<=@)\w+ 匹配 example(?=@) 查找到位置为 @ 的右侧 @|example.com\w+ 在零宽断言的左边,匹配到 example
posted @ 2025-10-31 11:20  芝士故梦  阅读(7)  评论(0)    收藏  举报