教程

正则表达式 (Regex) 从入门到精通:全面指南

深入了解正则表达式的基本语法、元字符、量词、边界匹配、分组捕获以及高级断言。包含常用正则示例与在线测试工具推荐。

什么是正则表达式?

正则表达式(Regular Expression,简称 Regex 或 Regexp)是一种用于描述、匹配和处理字符串的强大工具。它通过一系列特定的字符组合(模式),来查找、验证或替换符合规则的文本。

无论是简单的手机号验证,还是复杂的日志分析,正则表达式都能极大地提高开发效率。几乎所有现代编程语言(如 JavaScript, Python, Java, C++, Go 等)都内置了对正则表达式的支持。

1. 基础语法

正则表达式主要由 普通字符元字符 组成。

普通字符

普通字符包括所有大写和小写字母、所有数字、所有标点符号和一些其他符号。它们在匹配时仅代表其字面含义。例如,模式 cat 将匹配字符串中的 “cat”。

元字符 (Metacharacters)

元字符是具有特殊含义的字符,是正则表达式的核心。

元字符描述
.匹配除换行符之外的任意单个字符。
\转义字符,将元字符转为普通字符,或标记特殊序列。
^匹配字符串或行的开始位置。
$匹配字符串或行的结束位置。
*匹配前面的子表达式零次或多次。
+匹配前面的子表达式一次或多次。
?匹配前面的子表达式零次或一次。
|逻辑“或”操作。
()标记一个子表达式的开始和结束位置,用于分组。
[]标记一个中括号表达式,匹配其中的任意字符。
{}标记量词表达式。

2. 字符类 (Character Classes)

字符类用于匹配一组字符中的任意一个。

  • [abc]:匹配 “a”、“b” 或 “c”。
  • [^abc]:匹配除 “a”、“b”、“c” 以外的任意字符。
  • [a-z]:匹配任意小写字母。
  • [A-Z]:匹配任意大写字母。
  • [0-9]:匹配任意数字。

常用简写:

  • \d:匹配数字,等同于 [0-9]
  • \D:匹配非数字,等同于 [^0-9]
  • \w:匹配字母、数字或下划线,等同于 [a-zA-Z0-9_]
  • \W:匹配非单词字符。
  • \s:匹配空白字符(空格、制表符、换行符等)。
  • \S:匹配非空白字符。

3. 量词 (Quantifiers)

量词用于指定某个模式出现的次数。

  • *:0 次或多次。
  • +:1 次或多次。
  • ?:0 次或 1 次(常用于表示可选)。
  • {n}:恰好 n 次。
  • {n,}:至少 n 次。
  • {n,m}:n 到 m 次。

贪婪与非贪婪匹配

  • 贪婪匹配 (Greedy):正则表达式默认是贪婪的,它会尽可能多地匹配字符。例如 a.*b 在匹配 axxxbxxxb 时会匹配整个字符串。
  • 非贪婪匹配 (Lazy/Non-greedy):在量词后面加上 ?(如 *?, +?)可以使其匹配尽可能短的字符串。例如 a.*?b 在匹配 axxxbxxxb 时只会匹配到第一个 axxxb

4. 边界匹配 (Anchors)

边界匹配符不匹配具体的字符,而是匹配“位置”。

  • ^:匹配字符串的开始(在多行模式下匹配行首)。
  • $:匹配字符串的结束(在多行模式下匹配行尾)。
  • \b:匹配单词边界。即单词字符(\w)与非单词字符之间的位置。
  • \B:匹配非单词边界。

5. 分组与捕获 (Grouping & Capturing)

  • (expression)捕获性分组。将匹配到的内容保存,方便后续通过 \1, \2 引用。
  • (?:expression)非捕获性分组。仅用于逻辑组合,不保存匹配结果,这样可以提高引擎的执行效率。
  • (?<name>expression)具名捕获分组。为组指定一个名称,在某些语言中可以通过名称提取数据。

6. 零宽断言 (Lookaround/环视) - 高级技巧

断言用于查找某些内容之前或之后的内容,但其本身“不消耗”字符,即断言部分不会出现在最终的匹配结果中。

  • (?=...) 正向肯定断言:后面必须跟着某内容。例如 Windows(?=95|98|NT) 只匹配后面跟有 95、98 或 NT 的 “Windows”。
  • (?!...) 正向否定断言:后面不能跟着某内容。
  • (?<=...) 反向肯定断言:前面必须是某内容。
  • (?<!...) 反向否定断言:前面不能是某内容。

7. 转义字符 (Escaping)

由于 *, +, ?, [, ], (, ), {, }, ., ^, $, |, \ 这些字符在正则中有特殊含义,如果你想匹配它们的字面含义,必须在前面加上反斜杠 \

例如,要匹配一个实际的点号 .,你应该写成 \.

8. 常用匹配模式 (Flags)

  • i (Ignore Case):忽略大小写。
  • g (Global):全局匹配(查找所有匹配项而非只停在第一个)。
  • m (Multiline):多行模式。使 ^$ 匹配每一行的开始和结束。
  • s (DotAll):点号可以匹配换行符。
  • u (Unicode):支持 Unicode 编码,对于匹配 Emoji 等多字节字符至关重要。

9. 实战示例

  • 匹配手机号 (中国)^1[3-9]\d{9}$
  • 匹配 Email^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
  • 匹配日期 (YYYY-MM-DD)^\d{4}-\d{2}-\d{2}$
  • 匹配 IP 地址 (基础格式)^(?:\d{1,3}\.){3}\d{1,3}$ (仅校验数字格式)
  • 匹配强密码^(?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,}$ (至少8位,包含字母和数字)

10. 性能与小贴士

  1. 避免“灾难性回溯”:尽量避免嵌套的模糊量词(如 (a+)+),这可能会导致引擎在某些输入下运行极其缓慢。
  2. 优先使用非捕获分组:如果你不需要提取括号内的内容,请使用 (?:...) 而非 (...)
  3. 具体胜过模糊:能用 [a-z] 就不要用 .,匹配范围越小,效率越高。
  4. 注意引擎差异:虽然基本语法通用,但不同语言(如 JavaScript、Python、PHP)的正则引擎对高级特性的支持(如反向断言/Lookbehind)有所不同。

总结

正则表达式是每个开发者都应该掌握的“瑞士军刀”。虽然起步阶段语法可能看起来比较晦涩,但一旦掌握,处理复杂文本时将游刃有余。

为了帮助您更直观地编写和测试正则表达式,我们提供了一个在线测试工具。

👉 立即体验:在线正则表达式测试工具

您可以直接在工具中输入正则表达式和待匹配文本,系统会实时高亮显示匹配结果,并提供详细的语法说明。