☰
learn-regex 正则表达式入门指南:从基础匹配、元字符到前后向断言与匹配模式
2026/9/30 1:49:56 网站建设 项目流程
  • 教程

【免费下载链接】learn-regex

Learn regex the easy way

项目地址:https://gitcode.com/gh_mirrors/le/learn-regex
点击查看免费下载

本文基于 learn-regex 仓库的韩国语翻译文档 translations/README-ko.md 整理编写(英文原版见 README.md),完整覆盖从"基础匹配器"到"元字符""前后向断言""标志位"与"贪婪/惰性匹配"的全部知识点。仓库中的每个示例都配有可复现的演示文本,读者学完后将能够独立解读并编写用于表单校验、文本替换、子串提取等场景的正则表达式。

什么是正则表达式?

正则表达式(Regular Expression)是一组用于在文本中查找特定模式的字符或符号集合。它通常作为一条"模式"(pattern),被从左到右地用于匹配目标字符串。因为 "Regular expression" 读起来过于拗口,人们通常将其缩写为regex、regexp,韩文文档中亦称정규식。

正则表达式最常见的三类用途:

  • 文本替换:在字符串内部查找并替换文本;
  • 格式校验:验证输入是否符合规定格式(如表单校验);
  • 按模式提取子串:基于模式匹配从字符串中抽取部分文本。

实战场景:用一条正则校验用户名

假设你在开发一个应用,需要为用户选择用户名设定规则:允许用户名包含字母、数字、下划线(_)和连字符(-),同时限制长度以免用户名看起来杂乱。可以使用下面这条正则:

^[a-z0-9_-]{3,15}$

这条表达式正是仓库教程开篇展示的实例,配图见 img/regexp-en.png。从配图的标注可以拆解出它的四个组成部分:

片段含义
^匹配输入字符串的开头(锚点)
[a-z0-9_-]字符集:只允许小写字母、数字、下划线、连字符
{3,15}量词:整体长度必须为3 到 15 个字符
$匹配输入字符串的结尾(锚点)

按此规则:

  • 可以接受:john_doe、jo-hn_doe、john12_as;
  • 无法匹配:Jo—— 因为其中包含大写字母J,且长度过短;
  • 从配图标注还可以看到,过短(如ab)、过长(如verylongusername1234)以及含特殊字符(如user@name)的字符串同样无法通过校验。

这条例子同时用到了下文要讲的三类核心语法:锚点(^$)、字符集([...])与花括号量词({n,m}),读完后续章节后你会对它形成完整理解。

1. 基础匹配器(Basic Matchers)

正则表达式本质上就是"用于在文本中执行搜索的字符模式"。例如正则the表示:字符t,后跟字符h,再后跟字符e。

"the" => The fat cat sat on the mat.

the只命中句中末尾的the,句首的The因首字母大写而未被匹配。同理,正则123匹配字符串123——引擎会逐一比较正则中的每个字符与输入字符串中的每个字符。

需要特别记住:正则默认区分大小写。因此正则The不会匹配小写的the:

"The" => The fat cat sat on the mat.

2. 元字符(Meta Characters)

元字符是正则表达式的"积木"。它们并不代表自身字面含义,而是被引擎以某种特殊方式解释。核心元字符总表如下:

元字符说明
.句点:匹配除换行符外的任意单个字符
[ ]字符类:匹配方括号内包含的任意字符
[^ ]否定字符类:匹配不包含在方括号内的任意字符
*匹配前一符号0 次或多次重复
+匹配前一符号1 次或多次重复
?使前一符号成为可选
{n,m}花括号:匹配前一符号至少 n 次、至多 m 次的重复
(xyz)字符组:按精确顺序匹配xyz
\|交替:匹配该符号之前的字符或之后的字符
\转义下一个字符,从而允许匹配保留字符[ ] ( ) { } . * + ? ^ $ \ |的字面量
^匹配输入字符串的开头
$匹配输入字符串的结尾

2.1 句点(.)

.是最简单的元字符示例:匹配任意单个字符,但不匹配回车符或换行符。正则.ar表示:任意单个字符,后跟a,再后跟r。

".ar" => The car parked in the garage.

命中结果为car、par(来自parked)、gar(来自garage)。

2.2 字符集(Character Sets)

字符集也叫字符类,用方括号[...]指定。方括号内的连字符-用于表示字符范围,且字符的排列顺序无关紧要。正则[Tt]he表示:大写T或小写t,后跟h,再后跟e。

"[Tt]he" => The car parked in the garage.

它同时命中了句首的The和句中的the。

需要留意:字符集内部的句点表示字面量句点。正则ar[.]表示:小写a,后跟r,再后跟一个句点字符。

"ar[.]" => A garage is a good place to park a car.

它只命中car.中的ar.。

2.2.1 否定字符集(Negated Character Sets)

一般情况下,脱字符^表示字符串的起始位置;但当它紧跟左方括号之后时,表示对字符集的否定。正则[^c]ar表示:除c外的任意字符,后跟a,再后跟r。

"[^c]ar" => The car parked in the garage.

car因c被排除而不匹配,只有par(来自parked)和gar(来自garage)命中。

2.3 重复(Repetitions)

元字符+、*、?用于指定某个子模式出现的次数,且在不同位置上有不同行为。

2.3.1 星号(*)

*匹配前一匹配器0 次或多次重复。正则a*表示小写a的 0 次或多次重复。若*紧跟在字符集/字符类之后,则表示整个字符集的重复。例如[a-z]*表示任意数量的小写字母连续出现:

"[a-z]*" => The car parked in the garage #21.

命中了he、car、parked、in、the、garage(句首The的T是大写所以只命中he,#21中的数字不匹配)。

*也可以与元字符.组合成.*,匹配任意字符串;与空白字符\s组合匹配一段空白。例如\s*cat\s*表示:0 个或多个空格,后跟小写c、a、t,再后跟 0 个或多个空格:

"\s*cat\s*" => The fat cat sat on the concatenation.

命中了cat(带前后空格)以及concatenation内部的cat。

2.3.2 加号(+)

+匹配前一字符1 次或多次重复。正则c.+t表示:小写c,后跟至少一个字符,再后跟小写t。由于+默认贪婪,这里的t是句中最后一个t:

"c.+t" => The fat cat sat on the mat.

命中的是整个cat sat on the mat。

2.3.3 问号(?)

?使前一字符变为可选,即匹配前一字符0 次或 1 次。先看对比:正则[T]he要求必须有大写T:

"[T]he" => The car is parked in the garage.

只命中句首的The。而[T]?he表示可选的大写T,后跟h、e:

"[T]?he" => The car is parked in the garage.

同时命中了The和句末的he。

2.4 花括号(Braces)

花括号(也叫量词)用于精确指定某个字符或字符组重复的次数。正则[0-9]{2,3}表示:0 到 9 之间的数字至少 2 次、至多 3 次连续出现:

"[0-9]{2,3}" => The number was 9.9997 but we rounded it off to 10.0.

命中999(9.9997中从 9 开始向后取 3 位)和10。

花括号还有两种省略写法:

  • 省略第二参数:[0-9]{2,}表示2 次或更多的数字:
"[0-9]{2,}" => The number was 9.9997 but we rounded it off to 10.0.

命中9997和10。

  • 同时省略逗号:[0-9]{3}表示恰好 3 次的数字:
"[0-9]{3}" => The number was 9.9997 but we rounded it off to 10.0.

只命中999。

2.5 捕获组(Capturing Groups)

捕获组是写在圆括号(...)内的子模式集合。如前所述,量词放在单个字符后表示重复该字符;而量词放在捕获组之后时,表示重复整个捕获组。例如(ab)*匹配字符组合 "ab" 的 0 次或多次重复。

交替符|也可以用在捕获组内部。例如(c|g|p)ar表示:小写c、g或p,后跟a,再后跟r:

"(c|g|p)ar" => The car is parked in the garage.

命中car、par(来自parked)、gar(来自garage)。

值得注意的是,捕获组不仅完成匹配,还会"捕获"字符供宿主语言使用——宿主语言可以是 Python、JavaScript 或任何在函数定义中实现了正则表达式的语言,从而支持后续的引用与提取。

2.5.1 非捕获组(Non-Capturing Groups)

非捕获组在匹配同样字符的同时不创建捕获组,写法是在(...)内以?:开头。例如(?:c|g|p)ar与(c|g|p)ar匹配结果完全相同,但不会产生捕获:

"(?:c|g|p)ar" => The car is parked in the garage.

非捕获组在查找-替换功能中非常实用;当它与捕获组混用时,也能让输出的捕获编号保持整洁清晰(详见下文 前后向断言)。

2.6 交替(Alternation)

竖线符|用于定义交替,相当于多个表达式之间的OR 条件。你可能会认为字符集和交替等价,但二者有本质区别:字符集在"字符"层面工作,而交替在"表达式"层面工作。例如(T|t)he|car表示:要么(T或t+h+e),要么(c+a+r):

"(T|t)he|car" => The car is parked in the garage.

命中The、car、the。

2.7 特殊字符转义(Escaping Special Characters)

反斜杠\用于转义紧随其后的字符,从而允许把保留字符{ } [ ] / \ + * . $ ^ | ?当作普通匹配字符使用。例如.默认匹配除换行外的任意字符;要匹配输入中的字面量句点,就把它写成\.。正则(f|c|m)at\.?表示:小写f、c或m,后跟a、t,再后跟一个可选的句点:

"(f|c|m)at\.?" => The fat cat sat on the mat.

命中了fat、cat以及带句点的mat.。

2.8 锚点(Anchors)

锚点用于检查匹配到的符号是否为输入字符串的起始符号或结束符号,共有两类:脱字符^和美元符$。

2.8.1 脱字符(^)

^检查匹配字符是否为输入字符串的第一个字符。将^a应用于abc会命中a;将^b应用于同一字符串则一无所获,因为b不是起始字符。看正则^(T|t)he——它要求T或t必须是字符串第一个字符,后跟h、e。对比两种写法:

"(T|t)he" => The car is parked in the garage.

命中The和the;而加上锚点后:

"^(T|t)he" => The car is parked in the garage.

只命中句首的The。

2.8.2 美元符($)

$检查匹配字符是否为字符串的最后一个字符。正则(at\.)会命中所有at.:

"(at\.)" => The fat cat. sat. on the mat.

命中三处at.。而(at\.)$要求匹配必须落在字符串末尾:

"(at\.)$" => The fat cat. sat. on the mat.

只有句末的mat.命中。

3. 字符集简写(Shorthand Character Sets)

正则提供了若干常用字符集的便捷简写:

简写说明
.除换行外的任意字符
\w匹配字母数字字符:[a-zA-Z0-9_]
\W匹配非字母数字字符:[^\w]
\d匹配数字:[0-9]
\D匹配非数字:[^\d]
\s匹配空白字符:[\t\n\f\r\p{Z}]
\S匹配非空白字符:[^\s]

例如开篇用户名规则中的[a-z0-9_-],若允许大写即可简写为[\w-]之类——注意简写类的语义要按上表逐项确认,避免误放宽范围。

4. 前后向断言(Lookaround)

后向断言(Lookbehind)与前向断言(Lookahead)合称Lookaround,它们是一种特殊的非捕获组:用于"匹配某个模式",但不把该模式本身纳入匹配结果。Lookaround 适用于"某模式必须出现在另一特定模式之前或之后"的条件场景。

举例:要从字符串$4.44 and $10.88中取出所有前面带美元符$的数字,可以用(?<=\$)[0-9\.]*,它表示:取所有前面是$、且可包含句点.的数字字符(注意\$是转义后的美元符字面量)。

四种 Lookaround 写法:

符号说明
?=正向前瞻(Positive Lookahead)
?!负向前瞻(Negative Lookahead)
?<=正向后顾(Positive Lookbehind)
?<!负向后顾(Negative Lookbehind)

4.1 正向前瞻(Positive Lookahead)

正向前瞻断言表达式的前半部分之后必须紧跟前瞻表达式,且返回的匹配结果只包含前半部分命中的文本。写法是在圆括号内使用(?=...),把前瞻表达式写在等号之后。

正则(T|t)he(?=\sfat)表示:匹配T或t后跟h、e,且仅当其后紧跟空白字符与单词fat:

"(T|t)he(?=\sfat)" => The fat cat sat on the mat.

只有The命中(它后面紧跟fat),句中the后是mat,不满足条件。

4.2 负向前瞻(Negative Lookahead)

负向前瞻用于获取后面不跟特定模式的所有匹配。写法与正向前瞻相同,只是把等号=换成感叹号!,即(?!...)。正则(T|t)he(?!\sfat)表示:获取所有后面不跟空格加fat的The或the:

"(T|t)he(?!\sfat)" => The fat cat sat on the mat.

只有句末的the命中(它后面是mat);The fat中的The因后面紧跟fat而不匹配。

4.3 正向后顾(Positive Lookbehind)

正向后顾用于获取前面是特定模式的所有匹配,写法为(?<=...)。正则(?<=(T|t)he\s)(fat|mat)表示:获取所有位于The/the加空格之后的fat或mat:

"(?<=(T|t)he\s)(fat|mat)" => The fat cat sat on the mat.

命中fat和句末的mat——它们都紧跟在The或the之后,且匹配结果只包含fat/mat本身,不含前导的The/the。

4.4 负向后顾(Negative Lookbehind)

负向后顾用于获取前面不跟特定模式的所有匹配,写法为(?<!...)。正则(?<!(T|t)he\s)(cat)表示:获取所有前面不是The/the加空格的cat:

"(?<!(T|t)he\s)(cat)" => The cat sat on cat.

第一个cat因前面紧跟The而不命中,只有句末独立出现的cat命中。

实践提示:后顾断言(Lookbehind)在部分老版本正则引擎(如某些 JavaScript 环境、部分 POSIX 风格引擎)中不受支持,跨语言复用此类模式前需先确认目标引擎的能力。

5. 标志位(Flags)

标志位也被称为修饰符(modifier),因为它们会改变正则匹配的输出行为。标志位可以按任意顺序、任意组合使用,并且是 RegExp 的组成部分(JavaScript 中写作模式末尾的gi、gm等形式)。

标志位说明
i忽略大小写:匹配不再区分大小写
g全局搜索:匹配所有实例,而非仅第一个
m多行模式:锚点元字符按每一行生效

5.1 忽略大小写(i)

修饰符i用于执行不区分大小写的匹配。正则/The/gi表示:T、h、e依次出现,末尾的i让引擎忽略大小写,g则用于在整个输入字符串中搜索。对比:

"The" => The fat cat sat on the mat.

只命中The;加上/The/gi后:

"/The/gi" => The fat cat sat on the mat.

同时命中The和句末的the。

5.2 全局搜索(g)

修饰符g执行全局匹配——找到所有匹配而不是在第一个匹配后停止。正则/.(at)/g表示:除换行外的任意字符,后跟a、t。默认(不加g)时:

"/.(at)/" => The fat cat sat on the mat.

只命中第一个fat;加上g后:

"/.(at)/g" => The fat cat sat on the mat.

命中fat、cat、sat、mat全部四处。

5.3 多行模式(m)

如锚点一节所述,^与$用于检查模式是否位于输入字符串的开始/结尾。若希望锚点对每一行都生效,就使用m标志。正则/.at(.)?$/gm表示:小写a、t依次出现,后跟一个可选的任意非换行字符,且因m标志,引擎会对字符串的每一行行尾进行匹配。对比:

"/.at(.)?$/" => The fat cat sat on the mat.

不加m时只命中最后一行行尾的mat.;加上/gm后:

"/.at(.)?$/gm" => The fat cat sat on the mat.

每行行尾的fat、sat、mat.全部命中。

6. 贪婪匹配 vs 惰性匹配(Greedy vs Lazy)

默认情况下,正则执行贪婪(greedy)匹配——尽可能匹配更长的文本;使用?可以切换为惰性(lazy)匹配——尽可能匹配最短的文本。

以/(.*at)/为例,.*会一直贪婪地延伸到最后一个at:

"/(.*at)/" => The fat cat sat on the mat.

命中整段The fat cat sat on the mat。而/(.*?at)/中在量词*后加了?,惰性匹配在找到第一个at后就停止:

"/(.*?at)/" => The fat cat sat on the mat.

只命中The fat。

实战提醒:在需要"最短匹配"的场景(例如提取一对引号/标签之间的内容)中,惰性量词*?、+?、??是避免过度匹配的关键;而"取到最后一个"的贪婪语义(如上一节c.+t)则常用于需要尾部约束的场景。

7. 在 learn-regex 仓库中继续深入

  • 多语言对照学习:仓库在 translations/ 目录下提供了 18 种语言的翻译版本(中文见 README-cn.md、英文原版见 README.md 等),适合以母语对照英文原版逐节巩固;
  • 新增翻译的协作方式:若希望为本仓库贡献新的语言版本,可参考 translations/how-to.md,其流程为:先在 Issues 中创建协作议题 → 通过 Pull Request 协作提交翻译 → 完成后通知维护者合入;
  • 许可协议:仓库以 MIT 协议开源,版权归原作者 Zeeshan Ahmad 所有,详见 LICENSE.md。

学完本指南后,你应当能够:识别并解释正则中的元字符、字符集、量词、分组与锚点;运用前后向断言做条件匹配;通过i/g/m标志调整匹配行为;并能区分贪婪与惰性匹配。以上全部示例均可在常见的在线正则调试工具中直接粘贴验证,请配合动手练习巩固理解。

  • 教程

【免费下载链接】learn-regex

Learn regex the easy way

项目地址:https://gitcode.com/gh_mirrors/le/learn-regex
点击查看免费下载

相关推荐

上一篇:nvidiaProfileInspector与VR技术:优化虚拟现实体验的设置
下一篇:ARM CCN 缓存一致性网络 perf PMU 驱动使用指南:从 sysfs 事件配置到 perf 实战

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询