跳过正文
正则表达式(Regex)指南
  1. Blog/

正则表达式(Regex)指南

·2470 字·5 分钟
目录

在编程和文本处理的世界里,正则表达式(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.+tThe 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)也叫修饰符,可以改变整个正则表达式的搜索行为。

标志名称描述
iCase Insensitive忽略大小写进行匹配
gGlobal Search全局搜索,查找所有匹配项,而不是找到第一个就停止
mMultiline多行模式。使 ^$ 能匹配每一行的开头和结尾,而不仅仅是整个字符串的开头和结尾
  • 示例/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),尝试构建和测试自己的模式,很快就能运用自如,解决各种复杂的文本处理难题。