正则表达式完全指南:从入门到实战

0 阅读3分钟

前言

正则表达式(Regular Expression,简称 Regex)是程序员手中最强大的文本处理工具之一。它像是一把精密的“手术刀”,能从杂乱无章的字符串中精准地提取、替换或验证数据。

然而,正则的语法往往晦涩难懂。本文将结合关于“贪婪模式”和“捕获组”的疑问,由浅入深地拆解正则的核心逻辑。


一、 核心概念:正则到底是什么?

简单来说,正则表达式就是一种描述字符串特征的语言

  • 普通字符串"abc" —— 只能匹配 "abc" 这三个字母。
  • 正则表达式\d{3}-\w+ —— 匹配“3个数字”、“一个横杠”、“任意多个单词字符”。

💡 Tip:写正则时,不要想着“我要找哪个词”,而要想着“我要找的这个词长什么样”。


二、 基础语法:构建匹配的积木

1. 元字符(Metacharacters)

元字符是正则中的特殊符号,它们不代表字面意思,而是代表一类字符。

符号含义示例匹配内容
.任意字符(除换行符)a.cabc, a1c, a c
\d数字 (digit)\d\d12, 99
\w单词字符 (word)\w+hello, user_1
\s空白字符 (space)a\sba b, a↹b
^开头^HelloHello world (首词)
$结尾end$The end (尾词)

2. 量词(Quantifiers):控制出现的次数

量词决定了前面的字符要出现多少次。

符号含义示例
*0次或多次ab*c → ac, abc, abbc
+1次或多次ab+c → abc, abbc (不匹配 ac)
?0次或1次ab?c → ac, abc
{n}恰好 n 次\d{3} → 123
{n,m}n 到 m 次\d{2,4} → 12, 123, 1234

三、 进阶核心:贪婪与非贪婪(痛点)

这是正则中最容易踩坑的地方之一。

1. 贪婪模式

默认行为。正则引擎会尽可能多地匹配字符,“吃掉”所有内容,如果不满足后续条件再吐出来(回溯)。

  • 写法.*, .+, \d+
  • 场景:匹配整行内容,或者确定没有嵌套结构时。

2. 非贪婪/懒惰模式

加上 ? 。正则引擎会尽可能少地匹配字符,一旦满足后续条件立即停止。

  • 写法.*?, .+?, \d+?
  • 场景HTML标签提取、成对符号之间的内容提取。

实战对比

假设文本为:<div>标题1</div><div>标题2</div>

  • 贪婪 <div>.*</div>

    • 结果:<div>标题1</div><div>标题2</div>
    • 原因:第一个 .* 一口气吞到了最后一个 </div>
  • 非贪婪 <div>.*?</div>

    • 结果:<div>标题1</div>
    • 原因:.*? 遇到第一个 </div> 就停下了。

四、 数据提取:分组与捕获

匹配只是第一步,把数据“扣”出来才是目的。

1. 捕获组 ()

括号不仅改变优先级,还会将匹配到的内容保存下来。

const str = "2023-10-05";
const reg = /(\d{4})-(\d{2})-(\d{2})/;
// $1 = 2023, $2 = 10, $3 = 05

2. 非捕获组 (?:)

如果你只需要括号来改变优先级(比如配合 |),但不需要保存内容,使用 ?: 可以节省内存并提高速度。

// 匹配 http 或 https,但不需要单独提取协议头
/(?:https?)://www/

3. 命名捕获组 (?<name>)

现代语言(JS ES2018+, Python, Java)支持给组起名字,代码可读性极大提升。

const reg = /(?<year>\d{4})-(?<month>\d{2})/;
// 结果.groups.year -> "2023"

五、 高级技巧:断言(Assertions)

断言只判断位置,不消耗字符(不占宽度)。

名称符号含义示例
正向先行(?=...)后面必须是...Windows(?=10) 匹配 Windows 10 中的 Windows
负向先行(?!...)后面不能是...Windows(?!10) 匹配 Windows 7 中的 Windows
正向后行(?<=...)前面必须是...(?<=$)\d+ 匹配 $100 中的 100
负向后行(?<!...)前面不能是...(?<!$)\d+ 匹配不带$的数字

六、 避坑指南与最佳实践

  1. HTML解析慎用正则:虽然正则能处理简单的 HTML,但面对复杂的嵌套、属性乱序时极其脆弱。生产环境建议使用 DOM 解析器(如 Cheerio, BeautifulSoup)。
  2. 性能陷阱:避免在量词中嵌套量词,如 (a+)+,这会导致灾难性回溯,让程序卡死。
  3. 开启多行模式:在处理多行文本块时,记得加 m 标志(让 ^$ 匹配每一行的首尾)或 s 标志(让 . 匹配换行符)。
  4. 善用工具:不要盲写。使用 Regex101 或 VS Code 的正则搜索功能实时调试。

七、 总结

掌握正则的三个阶段:

  1. 入门:理解 \d, \w, . 和基本量词。
  2. 熟练:深刻理解贪婪与非贪婪的区别,熟练使用捕获组提取数据。
  3. 精通:掌握断言处理复杂逻辑,了解引擎回溯原理以优化性能。

正则表达式是一门“写时痛苦,用时爽快”的技能。希望这篇文章能帮你初步认识正则表达式!