正则表达式模式速查表:常用表达式详解
· 12分钟阅读
目录
正则表达式(regex)是开发者工具库中最强大的工具之一。无论您是在验证电子邮件地址、解析日志文件、从文本中提取数据,还是构建复杂的搜索替换操作,正则表达式都提供了一种简洁灵活的方式来处理文本模式。
本综合指南涵盖了从基本语法到高级技巧的所有内容,并提供了可以立即在项目中使用的实用示例。我们将探索不同编程语言中的正则表达式,分享性能优化技巧,并帮助您避免即使是经验丰富的开发者也会遇到的常见错误。
正则表达式基础
从本质上讲,正则表达式是定义搜索模式的字符序列。当您对字符串运行此模式时,正则表达式引擎会尝试根据您指定的规则查找匹配项。
正则表达式模式由两种类型的字符组成:完全匹配自身的字面字符,以及具有特殊含义的元字符。例如,模式/hello/匹配字符串中任何位置的字面文本"hello"。但/h.llo/使用点元字符来匹配"hello"、"hallo"、"hxllo"或任何其他以"h"开头并以"llo"结尾的五字符序列。
基本元字符
以下是您每天都会使用的最基本的正则表达式元字符参考表:
| 元字符 | 描述 | 示例 | 匹配 |
|---|---|---|---|
. |
任何单个字符(换行符除外) | c.t |
cat, cot, c9t, c@t |
\d |
任何数字 [0-9] | \d{3} |
123, 456, 789 |
\D |
任何非数字 | \D+ |
abc, XYZ, @#$ |
\w |
单词字符 [a-zA-Z0-9_] | \w+ |
hello, test_123 |
\W |
非单词字符 | \W |
@, #, 空格, ! |
\s |
空白字符(空格、制表符、换行符) | \s+ |
单个或多个空格 |
\S |
非空白字符 | \S+ |
任何可见字符 |
\b |
单词边界 | \bcat\b |
"cat"但不匹配"category" |
^ |
字符串/行的开始 | ^Hello |
以"Hello"开头的行 |
$ |
字符串/行的结束 | end$ |
以"end"结尾的行 |
专业提示:使用正则表达式测试器实时试验这些模式。您可以针对自己的示例文本进行测试,并立即看到突出显示的匹配项。
转义特殊字符
当您需要匹配字面元字符(如点或星号)时,必须使用反斜杠对其进行转义。例如,\.匹配字面句点,\*匹配字面星号。
需要转义的字符包括:. * + ? ^ $ { } [ ] ( ) | \
字符类与量词
字符类允许您定义要匹配的字符集,而量词指定模式应重复的次数。它们共同构成了大多数正则表达式模式的基础。
字符类
方括号创建一个字符类,匹配括号内的任何单个字符:
| 模式 | 描述 | 示例匹配 |
|---|---|---|
[abc] |
匹配 a、b 或 c | a, b, c(一个字符) |
[^abc] |
匹配除 a、b 或 c 之外的任何字符 | d, e, 1, @ 等 |
[a-z] |
匹配任何小写字母 | a 到 z |
[A-Z] |
匹配任何大写字母 | A 到 Z |
[0-9] |
匹配任何数字 | 0 到 9(与 \d 相同) |
[a-zA-Z] |
匹配任何字母 | 所有字母,任何大小写 |
[a-zA-Z0-9] |
匹配任何字母数字 | 字母和数字 |
[a-z&&[^aeiou]] |
仅辅音(交集) | b, c, d, f, g 等 |
量词
量词指定前面的元素应匹配多少次。它们对于匹配不同长度的模式至关重要:
*— 零次或多次(贪婪)+— 一次或多次(贪婪)?— 零次或一次(可选){3}— 恰好3次{3,}— 3次或更多次{3,6}— 3到6次之间*?— 零次或多次(懒惰/非贪婪)+?— 一次或多次(懒惰/非贪婪)??— 零次或一次(懒惰)
贪婪匹配与懒惰匹配
理解贪婪量词和懒惰量词之间的区别对于编写高效的正则表达式模式至关重要。默认情况下,量词是贪婪的 — 它们在仍然允许整体模式匹配的情况下尽可能多地匹配文本。
考虑字符串"<div>content</div><div>more</div>"的这个例子:
- 贪婪:
<div>.*</div>从第一个<div>到最后一个</div>匹配整个字符串 - 懒惰:
<div>.*?</div>分别匹配每个<div>...</div>对
懒惰版本在量词后添加?,告诉正则表达式引擎在仍然满足模式的情况下尽可能少地匹配。
快速提示:在解析HTML或XML时,始终使用懒惰量词以避免跨多个标签匹配。更好的做法是,对于复杂的标记使用适当的解析器库而不是正则表达式。
常用正则表达式模式
以下是经过实战检验的常见验证和提取任务的正则表达式模式。这些模式在全球的生产应用程序中使用。
电子邮件验证
一个涵盖大多数实际情况的实用电子邮件验证模式:
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
此模式确保电子邮件具有本地部分(@ 之前)、域名和有效的顶级域。请注意,仅使用正则表达式无法实现完美的电子邮件验证 — 官方RFC 5322标准非常复杂。对于生产使用,请考虑使用专用的电子邮件验证库。
电话号码
带有可选国家代码和各种格式的美国电话号码:
^(\+1[-.\s]?)?(\(?\d{3}\)?[-.\s]?)?\d{3}[-.\s]?\d{4}$
这匹配以下格式:
- 555-123-4567
- (555) 123-4567
- +1 555 123 4567
- 5551234567
URL
匹配带有可选www前缀的HTTP和HTTPS URL:
^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$
IP地址
IPv4地址验证:
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
这确保每个八位字节在0到255之间。
日期
ISO 8601日期格式(YYYY-MM-DD):
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$
美国日期格式(MM/DD/YYYY):
^(0[1-9]|1[0-2])\/(0[1-9]|[12][0-9]|3[01])\/\d{4}$
信用卡号码
基本信用卡验证(删除空格和破折号):
^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|3[47][0-9]{13}|6(?:011|5[0-9]{2})[0-9]{12})$
此模式验证Visa、MasterCard、American Express和Discover卡。始终使用Luhn算法进行实际验证。
密码
强密码要求至少8个字符、一个大写字母、一个小写字母、一个数字和一个特殊字符:
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$
这使用前瞻断言(在下一节中介绍)来确保满足所有要求。
锚点、分组与前瞻
这些高级功能使您能够精确控制匹配发生的位置以及如何捕获模式。
锚点
锚点不匹配字符 — 它们匹配字符串中的位置:
^— 字符串的开始(或多行模式下的行)$— 字符串的结束(或多行模式下的行)\b— 单词边界(\w 和 \W 之间)\B— 非单词边界\A— 字符串的开始(始终,即使在多行模式下)\Z— 字符串的结束(始终,即使在多行模式下)
示例:\bcat\b匹配"cat"作为整个单词,但不匹配"category"或"concatenate"中的"cat"。
捕获组
括号创建捕获组,提取匹配的子字符串:
^(\d{3})-(\d{3})-(\d{4})$
此模式匹配电话号码并分别捕获区号、前缀和线路号码。您可以在替换字符串中引用这些捕获或以编程方式提取它们。
非捕获组
当您需要分组但不想捕获匹配时,使用(?:...):
(?:https?|ftp)://[^\s]+
这匹配以http、https或ftp开头的URL,而不为协议创建捕获组。
命名捕获组
命名组使您的正则表达式更具可读性和可维护性:
(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
您可以按名称而不是按编号引用这些,使您的代码更清晰。
前瞻断言
前瞻检查前面是否存在模式而不消耗字符:
(?=...)— 正向前瞻(必须后跟)(?!...)— 负向前瞻(不得后跟)
示例:\d+(?= dollars)匹配后跟" dollars"的数字,但不在匹配中包含" dollars"。
后顾断言
后顾检查当前位置之前的内容:
(?<=...)— 正向后顾(必须前面有)(?<!...)— 负向后顾(不得前面有)
示例:(?<=\$)\d+匹配前面有美元符号的数字,但不在匹配中包含$。
请注意,JavaScript仅在ES2018中获得了后顾支持,因此如果您要支持较旧的浏览器,请检查兼容性。
JavaScript中的正则表达式
JavaScript通过RegExp对象和字符串方法提供强大的正则表达式支持。以下是如何在JavaScript应用程序中有效使用正则表达式。
创建正则表达式模式
您可以通过两种方式创建正则表达式模式:
// 字面量表示法(静态模式首选)
const pattern1 = /\d{3}-\d{3}-\d{4}/;
// 构造函数(对动态模式有用)
const pattern2 = new RegExp('\\d{3}-\\d{3}-\\d{4}');
注意构造函数中的双反斜杠 — 您需要在字符串中转义反斜杠。
正则表达式标志
JavaScript支持几个修改正则表达式行为的标志: