正则表达式速查表:常用模式与快速参考
· 12分钟阅读
正则表达式是开发者工具箱中最强大的工具之一,但对许多程序员来说仍然令人生畏。这份全面的速查表将正则表达式模式分解为易于理解的部分,并提供可以立即使用的实用示例。
无论您是在验证电子邮件地址、解析日志文件,还是清理混乱的数据,本指南都将帮助您更快地编写更好的正则表达式模式。我们将涵盖从基本字符匹配到高级环视断言的所有内容。
正则表达式基础
正则表达式(regex或regexp)是用于匹配字符串中字符组合的模式。它们几乎在所有编程语言中都受支持——JavaScript、Python、Java、PHP、Ruby、Go等等——以及文本编辑器如VS Code、Sublime Text,以及命令行工具如grep和sed。
从本质上讲,正则表达式模式由两种类型的字符组成:字面字符完全匹配自身,以及元字符具有特殊含义并定义匹配规则。
最简单的正则表达式是字面字符串。模式hello精确匹配文本"hello"出现的任何位置。但真正的威力来自元字符,它们增加了灵活性——比如匹配任何数字、重复模式或锚定到特定位置。
专业提示:使用我们的正则表达式测试器实时试验模式。您将在输入时立即看到高亮显示的匹配项,这使得理解模式的工作方式变得更加容易。
字面字符与元字符
正则表达式模式中的大多数字符都是字面的——它们匹配自身。模式cat按确切顺序匹配字母c、a和t。但是,某些字符具有特殊含义:
. ^ $ * + ? { } [ ] \ | ( )是元字符- 要按字面匹配这些字符,请使用反斜杠转义:
\.匹配句点 - 在字符类
[]内,大多数元字符失去其特殊含义
例如,example\.com按字面匹配"example.com",而example.com会匹配"exampleXcom",因为未转义的点匹配任何字符。
字符类
字符类允许您从一组可能性中匹配一个字符。它们是灵活模式匹配的基础,有两种形式:预定义的简写类和自定义括号表达式。
| 模式 | 匹配 | 示例 |
|---|---|---|
. |
除换行符外的任何字符 | h.t → hat、hot、hit、h@t |
\d |
任何数字[0-9] | \d{3} → 123、456、789 |
\D |
任何非数字 | \D+ → abc、xyz、@#$ |
\w |
单词字符[a-zA-Z0-9_] | \w+ → hello_world、var123 |
\W |
非单词字符 | \W → @、#、空格、标点符号 |
\s |
空白字符(空格、制表符、换行符) | \s+ → 任何空白序列 |
\S |
非空白字符 | \S+ → 任何可见字符 |
[abc] |
a、b或c中的任何一个 | [aeiou] → 任何元音 |
[^abc] |
不是a、b或c | [^0-9] → 任何非数字 |
[a-z] |
范围:a到z | [A-Za-z] → 任何字母 |
[a-z0-9] |
多个范围 | [a-fA-F0-9] → 十六进制数字 |
自定义字符类
括号表达式[]允许您定义自己的字符集。在括号内,大多数元字符失去其特殊含义——您不需要转义它们。
[aeiou]匹配任何单个元音[0-9]匹配任何数字(等同于\d)[a-zA-Z]匹配任何字母,大写或小写[^0-9]匹配除数字外的任何内容(^否定该类)[a-z-]匹配小写字母或连字符(末尾的连字符是字面的)
快速提示:字符类中字符的顺序无关紧要。[abc]和[bca]是相同的。如果任何字符存在,该类就会匹配。
实用示例
以下是字符类的一些实际应用:
[A-Z][a-z]+匹配大写单词,如"Hello"或"World"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}匹配IP地址(基本模式)[a-fA-F0-9]{6}匹配十六进制颜色代码,如"FF5733"[^\s]+匹配任何非空白序列(最广义的"单词")
量词和重复
量词指定模式应重复多少次。它们放在您想要重复的元素之后——字符、字符类或分组。
| 量词 | 含义 | 示例 |
|---|---|---|
* |
0次或多次 | ab*c → ac、abc、abbc、abbbc |
+ |
1次或多次 | ab+c → abc、abbc(不是ac) |
? |
0次或1次(可选) | colou?r → color、colour |
{n} |
恰好n次 | \d{4} → 2026、1999 |
{n,} |
n次或更多次 | \w{3,} → 3个或更多字符的单词 |
{n,m} |
n到m次之间 | \d{2,4} → 12、123、1234 |
*? |
懒惰/最小匹配(0次或多次) | <.*?> → 仅第一个标签 |
+? |
懒惰/最小匹配(1次或多次) | ".+?" → 第一个引号字符串 |
?? |
懒惰/最小匹配(0次或1次) | \d?? → 如果可能匹配0个数字 |
贪婪匹配与懒惰匹配
这是正则表达式中最重要的概念之一。默认情况下,量词是贪婪的——它们在仍然允许整体模式匹配的情况下匹配尽可能多的文本。
考虑HTML字符串<b>bold</b> and <i>italic</i>:
<.*>(贪婪)匹配从第一个<到最后一个>的整个字符串<.*?>(懒惰)分别匹配<b>、然后</b>、然后<i>、然后</i>
在量词后添加?使其变为懒惰(也称为非贪婪或最小)。它在仍然允许模式成功的情况下匹配尽可能少的文本。
专业提示:在提取分隔符之间的内容(引号、标签、括号)时,几乎总是使用懒惰量词。模式".*?"正确提取单个引号字符串,而".*"会从整个文本中的第一个引号匹配到最后一个引号。
常用量词模式
以下是您将经常使用的模式:
\d+匹配一个或多个数字(如42、1000、7等数字)\w+匹配一个或多个单词字符(标识符、变量名)\s*匹配可选的空白(零个或多个空格/制表符).+?懒惰地匹配任何字符(标记之间的内容)[a-z]{2,}匹配至少有2个小写字母的单词\d{3}-\d{3}-\d{4}匹配电话号码,如555-123-4567
锚点和边界
锚点不匹配字符——它们匹配字符串中的位置。它们对于确保模式在特定位置匹配而不是在文本中的任何位置匹配至关重要。
| 锚点 | 位置 | 示例 |
|---|---|---|
^ |
字符串开头(或带m标志的行) | ^Hello → 匹配"Hello world"但不匹配"Say Hello" |
$ |
字符串结尾(或带m标志的行) | end$ → 匹配"The end"但不匹配"end of story" |
\b |
单词边界 | \bcat\b → 匹配"cat"但不匹配"category" |
\B |
非单词边界 | \Bcat\B → 匹配"concatenate"但不匹配"cat" |
\A |
字符串开头(永不行) | 类似^但忽略多行模式 |
\Z |
字符串结尾(永不行) | 类似$但忽略多行模式 |
单词边界解释
单词边界\b非常有用但经常被误解。它匹配单词字符(\w)和非单词字符(\W)之间的位置,或字符串的开头/结尾。
考虑将模式\bcat\b应用于不同的字符串:
- "the cat sat" → 匹配(cat被空格包围)
- "category" → 不匹配(cat后面跟着单词字符'e')
- "concatenate" → 不匹配(cat前后都是单词字符)
- "cat" → 匹配(cat在字符串的开头和结尾)
- "cat!" → 匹配(cat后面跟着标点符号,一个非单词字符)
这使得\b非常适合查找完整单词,而不会意外匹配较大单词的部分。
开始和结束锚点
^和$锚点对于验证至关重要。当您想确保整个字符串匹配模式(而不仅仅是包含它)时,请用这些锚点包装您的模式。
^\d+$确保整个字符串都是数字(验证数字输入)^[A-Z]确保字符串以大写字母开头[.!?]$确保字符串以标点符号结尾^https?://确保URL以http://或https://开头
快速提示:在验证用户输入(电子邮件、电话、用户名)时,始终使用^和$来锚定您的模式。没有它们,模式\d{3}会接受"abc123def",而您可能想拒绝任何不是恰好3个数字的内容。
分组和捕获
括号()在正则表达式中有两个用途:它们将模式的各部分组合在一起,并捕获匹配的文本以供以后使用。这是正则表达式在提取和转换方面真正强大的地方。
| 语法 | 用途 | 示例 |
|---|---|---|
(abc) |
捕获组 | (\d{3})-(\d{4})捕获区号和号码 |
(?:abc) |
非捕获组 | (?:https?://)?example\.com分组但不捕获 |
(a|b) |
交替(或) | (cat|dog)匹配"cat"或"dog" |
\1 |
对组1的反向引用 | (\w+)\s+\1匹配重复的单词,如"the the" |
(?<name>abc) |
命名捕获组 | (?<year>\d{4})-(?<month>\d{2})用于日期 |
捕获组
当您将模式的一部分用括号括起来时,正则表达式引擎会捕获匹配的文本。然后,您可以在代码中引用这些捕获,甚至在正则表达式本身中使用反向引用。
例如,将模式(\d{3})-(\d{3})-(\d{4})应用于"555-123-4567"会创建三个捕获:
- 组1:"555"
- 组2:"123"
- 组3:"4567"
在大多数编程语言中,您可以通过匹配对象或替换字符串访问这些捕获。这使您可以轻松重新格式化数据——使用替换如($1) $2-$3将"555-123-4567"转换为"(555) 123-4567"。
非捕获组
有时您需要分组来使用量词或交替,但不需要捕获文本。使用(?:...)