正则表达式 (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. 性能与小贴士
- 避免“灾难性回溯”:尽量避免嵌套的模糊量词(如
(a+)+),这可能会导致引擎在某些输入下运行极其缓慢。 - 优先使用非捕获分组:如果你不需要提取括号内的内容,请使用
(?:...)而非(...)。 - 具体胜过模糊:能用
[a-z]就不要用.,匹配范围越小,效率越高。 - 注意引擎差异:虽然基本语法通用,但不同语言(如 JavaScript、Python、PHP)的正则引擎对高级特性的支持(如反向断言/Lookbehind)有所不同。
总结
正则表达式是每个开发者都应该掌握的“瑞士军刀”。虽然起步阶段语法可能看起来比较晦涩,但一旦掌握,处理复杂文本时将游刃有余。
为了帮助您更直观地编写和测试正则表达式,我们提供了一个在线测试工具。
👉 立即体验:在线正则表达式测试工具
您可以直接在工具中输入正则表达式和待匹配文本,系统会实时高亮显示匹配结果,并提供详细的语法说明。