正则表达式:基础字符与字符类

本篇从“一个模式如何匹配一个字符”开始。除非特别说明,regex 代码块只表示模式本身,不含 JavaScript 字面量的 /.../ 分隔符。可运行练习以 Python re 为基线;涉及字符类时会明确说明 Unicode 与 ASCII 差异。

1. 普通字符

功能说明

字母、数字和大多数非保留标点在正则中是普通字符。它们会匹配自身,且通常区分大小写。多个普通字符连在一起时,表示按顺序匹配该段文本。

语法格式

普通文本

简单示例

cat

测试文本:a cat and a catalog

匹配结果说明

模式会匹配文本中的 cat 两次:一次来自独立单词 cat,另一次来自 catalog 的开头。若只想匹配完整单词,需要结合 单词边界。

2. 元字符

功能说明

元字符在正则中具有特殊含义,常见的有 .、^、$、*、+、?、(、)、[、]、{、}、| 和 \。它们用于描述“任意字符、边界、重复、分组、选择”等规则,而不是匹配字面字符。

语法格式

元字符 + 其他模式

简单示例

ca.t

测试文本:cat cart cast

匹配结果说明

点号 . 是元字符,默认匹配一个任意字符(通常不含换行)。因此 ca.t 会匹配 cart 和 cast,但不会匹配只有三个字符的 cat。若需要匹配真正的句点,应写成 \.。

3. 转义字符

功能说明

反斜杠 \ 用于转义:它可以让元字符失去特殊意义,也可以引入 \d、\b 等特殊字符类或边界。若正则模式又放进编程语言的字符串中,常常还需要经历一次字符串层面的转义。

语法格式

\元字符

简单示例

file\.txt

测试文本:file.txt fileXtxt

匹配结果说明

\. 会匹配字面句点,所以结果是 file.txt;fileXtxt 不匹配。Python 通常写成 re.compile(r"file\.txt");PowerShell 模式可放在单引号字符串 'file\.txt' 中;JavaScript 字面量可写为 /file\.txt/。如果改用普通程序字符串,还要核对宿主语言的转义层。

4. 字符集合:[abc]

功能说明

字符集合(也叫字符组)用方括号表示“匹配其中任意一个字符”。[abc] 每次只匹配一个。

语法格式

[字符1字符2字符3]

简单示例

gr[ae]y

测试文本:gray grey gruy

匹配结果说明

gr[ae]y 会匹配 gray 和 grey,因为方括号位置允许 a 或 e;gruy 不匹配。方括号中的大多数元字符会变成普通字符,但 ]、-、^ 和 \ 仍需谨慎处理。

5. 字符范围:[a-z]

功能说明

在字符集合中,连字符 - 可表示范围。[a-z] 代表从 a 到 z 的任意一个小写 ASCII 字母;范围可以组合,如 [A-Za-z0-9]。

语法格式

[起始字符-结束字符]

简单示例

[A-Z][a-z]+

测试文本:Alice BOB alice Zhang

匹配结果说明

结果是 Alice 和 Zhang:第一个字符必须是大写字母,后面至少一个字符必须是小写字母。BOB 不符合后续小写字母要求,alice 的首字母不是大写。范围受引擎和字符编码影响;处理国际化文字时,不要假定 [a-z] 能覆盖所有字母。

6. 排除字符集合:[^0-9]

功能说明

当脱字符 ^ 出现在字符集合开头时,表示“不是这些字符中的任何一个”。例如 [^0-9] 匹配一个非 ASCII 数字字符。这里的 ^ 与行首锚点的含义不同,位置决定了它的作用。

语法格式

[^不允许的字符或范围]

简单示例

[^0-9]+

测试文本:A12-B_3

匹配结果说明

模式会匹配两段非数字文本:A 和 -B_。末尾的 + 表示连续的非数字合并为一次匹配;数字 1、2、3 不会被匹配。

7. 数字字符类:\d

功能说明

\d 是数字字符类。ECMAScript 中它表示 [0-9];Python 的 Unicode str 模式和 .NET 默认会接受其他 Unicode 十进制数字。机器协议、时间戳和标识符若只允许 ASCII 数字,应明确写 [0-9],或在 Python 中有意识地使用 re.ASCII。

语法格式

\d

简单示例

\d{4}

测试文本:编号 2026,批次 73

匹配结果说明

结果是 2026,因为 {4} 要求连续四个数字;73 只有两个数字,不匹配。

8. 非数字字符类:\D

功能说明

\D 匹配一个非数字字符,是 \d 的互补形式。它适合提取或排除数字之外的内容,但不会自动保证剩余文本是字母。

语法格式

\D

简单示例

\D+

测试文本:v2.0-beta

匹配结果说明

结果依次为 v、. 和 -beta。数字 2 与 0 被跳过;+ 把相邻的非数字字符合并在同一次匹配中。

9. 单词字符类:\w

功能说明

\w 匹配一个“单词字符”,但“单词”是引擎术语,不是自然语言分词。Python 的 Unicode str 模式默认包含 Unicode 字母数字与下划线,因此可匹配中文;ECMAScript 的基础集合接近 [A-Za-z0-9_];.NET 采用 Unicode 字符类别。机器标识符应优先写出允许集合,而不是依赖默认 \w。

语法格式

\w

简单示例

\w+

测试文本:user_name-01 张三

匹配结果说明

在 ECMAScript 的基础语义下,结果是 user_name 和 01;Python 默认还会匹配 张三。连字符和空格不是单词字符。这个差异正说明:同一模式不能脱离引擎与标志讨论。

10. 非单词字符类:\W

功能说明

\W 匹配一个非单词字符,是 \w 的互补形式。它常用于定位标点、分隔符和空白,但具体范围随着 \w 的定义而变化。

语法格式

\W

简单示例

\W+

测试文本:name@example.com!

匹配结果说明

结果是 @、. 和 !。字母属于 \w,所以不会被该模式匹配。

11. 空白字符类:\s

功能说明

\s 匹配一个空白字符,如空格、制表符和换行符;具体是否包含更多 Unicode 空白字符由引擎决定。它常用于处理不规则的空格与换行。

语法格式

\s

简单示例

\s+

测试文本:姓名 年龄\t城市

匹配结果说明

结果是两个空白片段:三个连续空格,以及一个制表符。+ 使连续空白被合并,而不是逐个返回。

12. 非空白字符类:\S

功能说明

\S 匹配一个非空白字符,是 \s 的互补形式。它适合提取由空白分隔的“非空白片段”,但不等同于自然语言中的单词。

语法格式

\S

简单示例

\S+

测试文本: one\ttwo three

匹配结果说明

结果是 one、two 和 three。开头、结尾和中间的空格或制表符不会被匹配。

13. 点号:.

功能说明

点号 . 默认匹配一个任意字符,但多数引擎默认不让它匹配换行符。开启单行(dotAll)模式后,点号通常也可匹配换行。若要匹配字面句点,必须使用 \.。

语法格式

.

简单示例

a.c

测试文本:abc a-c ac

匹配结果说明

结果是 abc 和 a-c:点号各匹配了中间的一个字符。ac 少了中间字符,不匹配。不要用 .* 代替所有结构化规则,它很容易写出过度匹配或低性能的表达式。

练习与自测

  1. 写一个只允许 ASCII 十六进制字符的字符类,并测试 0fA9、0x10、空字符串。
  2. 在 Python 中分别用 r"\d+"、r"[0-9]+" 匹配全角数字 123,解释结果差异。
  3. 写出匹配字面文本 a+b.c 的模式;说明哪些字符需要转义。
  4. [^0-9] 是否等于“字母”?为什么?
  5. . 在默认模式下为什么不能可靠表示“任意字节”或“任意一行 JSON”?

上一节:任务建模与引擎差异|下一节:边界与数量词。