开发者正则表达式速查表

· 12分钟阅读

目录

正则表达式简介

正则表达式(regex)是每个开发者都应该掌握的强大模式匹配工具。它们提供了一种简洁、声明式的方式来搜索、验证和操作文本数据,而无需编写冗长的字符串操作代码。

无论您是在构建表单验证、解析日志文件、从API提取数据,还是清理数据集,正则表达式都能提供优雅的解决方案。单个正则表达式模式可以替代数十行条件逻辑,使您的代码更易于维护且更不容易出错。

JavaScript、Python、Java、PHP和Ruby等现代编程语言都内置了正则表达式支持。一旦学会了语法,您就可以在几乎任何开发环境中应用这些技能。

专业提示:正则表达式起初可能看起来很神秘,但它们遵循一致的模式。从简单的表达式开始,随着信心的增长逐渐增加复杂性。使用在线正则表达式测试工具进行实验并实时可视化匹配结果。

基本语法和元素

在处理复杂模式之前,理解正则表达式的基本构建块至关重要。这些核心元素构成了您将编写的每个正则表达式的基础。

字面字符

最简单的正则表达式模式完全按照字符出现的方式匹配字面字符。模式cat匹配文本中出现的字符串"cat"。

大多数字母数字字符都是字面的,但某些特殊字符(称为元字符)具有特殊含义,当您想要按字面匹配它们时,必须使用反斜杠进行转义。

基本元字符

模式 描述 示例 匹配
. 匹配除换行符外的任何单个字符 c.t "cat"、"cot"、"c9t"
^ 断言字符串开始位置 ^Hello "Hello world"(仅在开头)
$ 断言字符串结束位置 world$ "Hello world"(仅在结尾)
* 匹配0次或多次重复 ab*c "ac"、"abc"、"abbc"
+ 匹配1次或多次重复 ab+c "abc"、"abbc"(不匹配"ac")
? 匹配0次或1次出现 colou?r "color"、"colour"
| 选择(OR运算符) cat|dog "cat"或"dog"
\ 转义特殊字符 \. 字面句点字符

转义特殊字符

当您需要按字面匹配元字符时,在它们前面加上反斜杠。例如,要匹配字面句点,使用\.而不是.

需要转义的常见字符包括:. * + ? ^ $ { } [ ] ( ) | \

// 匹配字面问号
const pattern = /What\?/;
pattern.test("What?"); // true

// 匹配美元金额
const price = /\$\d+\.\d{2}/;
price.test("$19.99"); // true

字符类和量词

字符类允许您匹配特定集合中的任何字符,而量词控制模式应重复多少次。它们共同构成了灵活模式匹配的支柱。

预定义字符类

描述 等效 示例
\d 任何数字 [0-9] \d{3}匹配"123"
\D 任何非数字 [^0-9] \D+匹配"abc"
\w 单词字符(字母数字+下划线) [A-Za-z0-9_] \w+匹配"user_123"
\W 非单词字符 [^A-Za-z0-9_] \W匹配"@"或" "
\s 空白字符(空格、制表符、换行符) [ \t\n\r\f\v] \s+匹配" "
\S 非空白字符 [^ \t\n\r\f\v] \S+匹配"hello"

自定义字符集

方括号定义自定义字符集。模式[aeiou]匹配任何单个元音字母,而[0-9a-fA-F]匹配任何十六进制数字。

在方括号内使用插入符号来否定集合:[^0-9]匹配任何不是数字的字符。

// 匹配任何元音字母
const vowels = /[aeiou]/gi;
"Hello World".match(vowels); // ["e", "o", "o"]

// 仅匹配辅音字母
const consonants = /[^aeiou\s]/gi;
"Hello".match(consonants); // ["H", "l", "l"]

量词详解

量词指定前面的元素应匹配多少次。默认情况下它们是贪婪的,这意味着它们匹配尽可能多的文本。

快速提示:在任何量词后添加问号使其变为非贪婪(惰性)。例如,.*?匹配尽可能少的字符而不是尽可能多的字符。这在提取分隔符之间的内容时至关重要。

锚点和单词边界

锚点不匹配字符——它们匹配字符串中的位置。当您需要确保文本出现在特定位置时,它们对于精确的模式匹配至关重要。

位置锚点

插入符号^匹配字符串(或多行模式下的行)的开始,而美元符号$匹配结束。这些对于整个字符串必须匹配模式的验证非常宝贵。

// 验证整个字符串都是数字
const onlyDigits = /^\d+$/;
onlyDigits.test("12345"); // true
onlyDigits.test("123abc"); // false

// 匹配以"Error"开头的行
const errorLines = /^Error/gm;
const logs = "Info: Starting\nError: Failed\nError: Timeout";
logs.match(errorLines); // ["Error", "Error"]

单词边界

\b锚点匹配单词边界——单词字符和非单词字符之间的位置。它非常适合匹配整个单词而不会意外匹配较大单词的一部分。

\B锚点匹配不是单词边界的位置。

// 仅匹配完整单词"cat"
const wholeCat = /\bcat\b/;
wholeCat.test("cat"); // true
wholeCat.test("cats"); // false
wholeCat.test("concatenate"); // false

// 匹配单词内的"cat"
const partialCat = /\Bcat\B/;
partialCat.test("concatenate"); // true
partialCat.test("cat"); // false

单词边界对于搜索和替换操作特别有用,当您想避免部分匹配时。在构建语法高亮器或代码分析器时,它们也是必不可少的。

分组和捕获

正则表达式中的括号有多种用途:它们将模式的各部分组合在一起,捕获匹配的文本以供以后使用,并在模式本身内启用反向引用。

捕获组

括号创建存储匹配文本的编号捕获组。您可以在替换字符串中引用这些捕获,或以编程方式提取它们。

// 提取日期组件
const datePattern = /(\d{4})-(\d{2})-(\d{2})/;
const match = "2026-03-31".match(datePattern);
// match[0]: "2026-03-31"(完整匹配)
// match[1]: "2026"(年)
// match[2]: "03"(月)
// match[3]: "31"(日)

// 使用捕获重新格式化日期
const text = "Date: 2026-03-31";
const reformatted = text.replace(/(\d{4})-(\d{2})-(\d{2})/, "$2/$3/$1");
// 结果:"Date: 03/31/2026"

非捕获组

使用(?:...)对模式进行分组而不创建捕获。当您只需要分组用于选择或量词时,这可以提高性能并保持捕获编号清晰。

// 分组但不捕获
const protocol = /(?:https?|ftp):\/\//;
protocol.test("https://example.com"); // true

// 与捕获比较(不必要的开销)
const protocolCapture = /(https?|ftp):\/\//;
// 创建了一个我们不需要的额外捕获组

命名捕获组

现代正则表达式引擎支持使用(?<name>...)语法的命名捕获。这使您的模式自文档化且更易于维护。

// 命名捕获以提高清晰度
const emailPattern = /(?<user>[\w.]+)@(?<domain>[\w.]+)/;
const match = "[email protected]".match(emailPattern);
console.log(match.groups.user); // "john.doe"
console.log(match.groups.domain); // "example.com"

// 在替换中使用
const masked = "[email protected]".replace(
  /(?<user>[\w.]+)@(?<domain>[\w.]+)/,
  "***@$<domain>"
);
// 结果:"***@example.com"

反向引用

使用\1\2等在同一模式内引用较早的捕获。这对于匹配重复或镜像模式非常强大。

// 匹配重复的单词
const repeated = /\b(\w+)\s+\1\b/;
repeated.test("hello hello"); // true
repeated.test("hello world"); // false

// 匹配HTML标签
const htmlTag = /<(\w+)>.*?<\/\1>/;
htmlTag.test("<div>content</div>"); // true
htmlTag.test("<div>content</span>"); // false

正则表达式标志和修饰符

标志修改正则表达式引擎解释模式的方式。在大多数语言中,它们添加在结束分隔符之后(例如,JavaScript中的/pattern/flags)。

常见标志

// 不区分大小写搜索
const pattern = /hello/i;
pattern.test("HELLO"); // true
pattern.test("Hello"); // true

// 全局标志用于多次匹配
const digits = /\d+/g;
"Phone: 555-1234, Fax: 555-5678".match(digits);
// ["555", "1234", "555", "5678"]

// 多行模式
const headers = /^#.+$/gm;
const markdown = "# Title\nContent\n## Subtitle";
markdown.match(headers); // ["# Title", "## Subtitle"]

专业提示:全局标志会改变exec()test()等方法的行为方式——它们在调用之间维护状态。如果您得到意外结果,请检查是否需要全局标志或它是否导致有状态匹配问题。

常见模式及其应用

让我们探索经过实战检验的常见开发任务正则表达式模式。这些模式经过实际使用的完善,可以处理您最初可能不会考虑的边缘情况。

电子邮件验证

由于RFC规范,电子邮件验证非常复杂,但这个实用模式可以处理99%的真实世界电子邮件地址:

const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

// 有效的电子邮件
emailPattern.test("[email protected]"); // true
emailPattern.test("[email protected]"); // true

// 无效的电子邮件
emailPattern.test("invalid@"); // false
emailPattern.test("@example.com"); // false
emailPattern.test("[email protected]"); // false

对于生产应用程序,请考虑使用专门的电子邮件验证库来处理国际化域名和所有RFC边缘情况。您还可以使用我们的电子邮件验证工具交互式测试电子邮件模式。

URL匹配

使用这个全面的模式从文本中匹配和提取URL:

const urlPattern
We use cookies for analytics. By continuing, you agree to our Privacy Policy.