正则表达式(Regex)指南

date
Jul 15, 2022
slug
正则表达式
status
Published
tags
正则表达式
杂项
summary
type
Post

从入门到精通:一份全面的正则表达式(Regex)指南

在编程和文本处理的世界里,正则表达式(Regular Expression,常缩写为 Regex 或 Regexp)是一个无比强大的工具。它能帮你从海量文本中,精准地查找、匹配和替换符合特定模式的字符串。无论你是前端开发者需要验证用户输入,还是后端工程师需要解析日志文件,掌握 Regex 都将让你事半功倍。
这篇指南将带你从最基础的概念开始,逐步深入到高级技巧,彻底掌握这个“文本瑞士军刀”。

什么是正则表达式?

简单来说,正则表达式是一组由字母、数字和特殊符号组成的“规则字符串”,它定义了你想要查找的文本模式。
它是一种从左到右匹配目标字符串的模式。想象一下,你想为一个应用设定用户名规则:必须包含小写字母、数字、下划线和连字符,并且长度在3到15个字符之间。
使用正则表达式,我们可以这样定义这个规则:
^[a-z0-9_-]{3,15}$
我们来拆解一下这个例子:
  • ^开始标记,表示匹配必须从字符串的开头开始。
  • [a-z0-9_-]字符集,表示允许的字符包括:所有小写字母(a-z)、所有数字(0-9)、下划线(_)和连字符(-)。
  • {3,15}量词,表示前面的字符集必须连续出现3到15次。
  • $结束标记,表示匹配必须在字符串的结尾结束。
根据这个规则,john_doejohn12-as 是合法的,但 Jo 就不合法,因为它包含了大写字母且长度太短。

1. 基本匹配

正则表达式最简单的形式就是直接匹配。它由一些字母和数字组合而成,会精确匹配一模一样的字符串。
  • 示例:正则表达式 the
  • 匹配The fat cat sat on **the** mat.
  • 注意:基本匹配是大小写敏感的。因此,The 不会匹配 the

2. 核心利器:元字符

元字符是 Regex 的精髓,它们不代表字面意思,而是有特殊的含义。

2.1 点运算符 .

. 是最简单的元字符,它能匹配除换行符外的任意单个字符
  • 示例c.t
  • 匹配The fat **cat** sat on the mat.

2.2 字符集 []

方括号 [] 用来定义一个字符集,表示匹配方括号内任意一个字符。
  • 示例[Tt]he
  • 匹配*The** car is parked in **the** garage.
否定字符集 [^]:如果在方括号内的开头使用 ^,则表示匹配除了方括号内字符以外的任意字符。
  • 示例[^c]ar
  • 匹配The car parked in the ga**rar**ge. (匹配了 rar,但跳过了 car)

2.3 重复次数(量词)

量词用来指定一个字符或字符组需要重复出现的次数。
符号
描述
示例
匹配
*
匹配0次或多次
\\s*cat\\s*
The fat** cat **sat on the concatenation.
+
匹配1次或多次
c.+t
The fat **cat sat on the mat**.
?
匹配0次或1次(表示可选)
[T]?he
**The** car is parked in **the** garage.
{n,m}
匹配最少n次,最多m次
[0-9]{2,3}
The number was 9.9997 but we rounded it off to **10**.
{n}
精确匹配n次
[0-9]{3}
The number was 9.**999**7 but we rounded it off to 10.0.

2.4 特征标群 ()

括号 () 用于将多个字符组合成一个单元(一个子模式)。量词可以作用于这个单元。
  • 示例(ab)*
  • 说明:匹配连续出现的 "ab" 零次或多次。

2.5 或运算符 |

竖线 | 的作用是“或”,用于匹配 | 左边或右边的表达式。
  • 示例(T|t)he|car
  • 匹配*The** **car** is parked in **the** garage.

2.6 转义特殊字符 \\

如果你想匹配元字符本身(如 .*?),需要在其前面加上反斜杠 \\ 进行转义。
  • 示例(f|c|m)at\\.?
  • 匹配The fat **cat** sat on the **mat.**

2.7 锚点 ^$

锚点用于将匹配锁定在字符串的特定位置。
  • ^:匹配字符串的开头
  • $:匹配字符串的结尾
  • 示例^(T|t)he 匹配以 Thethe 开头的字符串。
  • 示例at\\.$ 匹配以 at. 结尾的字符串。

3. 简写字符集

为了方便,Regex 提供了一些常用字符集的简写形式。
简写
等同于
描述
\\w
[a-zA-Z0-9_]
匹配字母、数字或下划线(单词字符)
\\W
[^\\w]
匹配非单词字符
\\d
[0-9]
匹配任意数字
\\D
[^\\d]
匹配任意非数字字符
\\s
[\\t\\n\\f\\r ]
匹配任意空白字符(空格、制表符、换行符等)
\\S
[^\\s]
匹配任意非空白字符
.
匹配除换行符外的所有字符

4. 高级技巧:零宽度断言

零宽度断言(Lookarounds)是一种强大的高级技巧。它们用于检查某个位置之前或之后是否符合特定模式,但这个模式本身不会被包含在最终的匹配结果中。它们只起到断言(判断)的作用,不消耗任何字符。
符号
类型
描述
(?=...)
正先行断言 (Positive Lookahead)
要求当前位置的后面能匹配 ... 模式
(?!...)
负先行断言 (Negative Lookahead)
要求当前位置的后面不能匹配 ... 模式
(?<=...)
正后发断言 (Positive Lookbehind)
要求当前位置的前面能匹配 ... 模式
(?<!...)
负后发断言 (Negative Lookbehind)
要求当前位置的前面不能匹配 ... 模式
  • 正先行断言示例(T|t)he(?=\\sfat)
    • 匹配*The** fat cat sat on the mat. (只匹配 "The",因为它后面跟着 " fat")
  • 负先行断言示例(T|t)he(?!\\sfat)
    • 匹配The fat cat sat on **the** mat. (只匹配第二个 "the",因为它后面没有跟着 " fat")
  • 正后发断言示例(?<=(T|t)he\\s)(fat|mat)
    • 匹配The **fat** cat sat on the mat. (只匹配 "fat",因为它前面是 "The ")
  • 负后发断言示例(?<!(T|t)he\\s)cat
    • 匹配The cat sat on **cat**. (只匹配第二个 "cat",因为它前面没有 "The " 或 "the ")

5. 模式的“开关”:标志

标志(Flags)也叫修饰符,可以改变整个正则表达式的搜索行为。
标志
名称
描述
i
Case Insensitive
忽略大小写进行匹配
g
Global Search
全局搜索,查找所有匹配项,而不是找到第一个就停止
m
Multiline
多行模式。使 ^$ 能匹配每一行的开头和结尾,而不仅仅是整个字符串的开头和结尾
  • 示例/the/gi
    • 说明g 表示全局搜索,i 表示忽略大小写。
    • 匹配*The** fat cat sat on **the** mat. (匹配所有 "the",不分大小写)

6. 贪婪与惰性匹配

默认情况下,量词(如 *+)是贪婪的(Greedy),它们会尽可能多地匹配字符。
  • 贪婪示例/(.*at)/
  • 匹配The fat cat sat on the mat. -> 匹配结果是 *The fat cat sat on the mat**
有时我们希望它尽可能少地匹配。这时,可以在量词后面加上一个 ?,使其变为惰性的(Lazy)
  • 惰性示例/(.*?at)/
  • 匹配The fat cat sat on the mat. -> 匹配结果是 *The fat** (匹配到第一个 at 就停止了)

结语

正则表达式初看起来可能像一堆天书般的符号,但一旦理解了其核心组件——元字符、量词、锚点和标志——就会发现它是一个逻辑严谨且功能强大的工具。
掌握 Regex 的最好方法就是不断练习。利用在线的 Regex 测试工具(如 regex101.com),尝试构建和测试自己的模式,很快就能运用自如,解决各种复杂的文本处理难题。
 

© Baiye 2022 - 2025