easy-vibe 正则表达式实战指南:从字符类到前瞻断言,用一行模式解决 80% 的文本检索与校验问题
2026/9/15 17:57:31 网站建设 项目流程

easy-vibe 正则表达式实战指南:从字符类到前瞻断言,用一行模式解决 80% 的文本检索与校验问题

【免费下载链接】easy-vibe💻 vibe coding 101|The first course for AI-native product builders.项目地址: https://gitcode.com/GitHub_Trending/ea/easy-vibe

导读:正则表达式看似天书,本质只是“描述文本模式的小型语言”。本篇以 easy-vibe 附录知识库《正则表达式基础》为骨架,完整覆盖字符类、量词、位置锚点与分组三大积木块,详解邮箱、手机号、密码强度等高频校验模式,并对照 Pythonre与 JavaScript 正则 API 给出可直接运行的代码示例;最后结合本仓库脚本(如 book-shared.mjs、generate-sitemap.mjs)中的真实正则用法,验证“贪婪与懒惰匹配”“分组捕获”“正则替换”等核心概念在生产代码中的实际形态。读完本文,你将具备用几行正则解决大多数文本查找、提取、替换与校验问题的实战能力。


1. 为什么需要正则表达式

先设想几个真实场景:

  • 从一份冗长的日志文件中提取所有 IP 地址;
  • 校验用户输入的邮箱格式是否合法;
  • 把文本中的日期从2024/01/15统一替换为2024-01-15
  • 从网页源码中提取所有链接。

如果用普通的字符串查找方法,你需要编写大量if-else分支逻辑,逐字符或逐子串判断;而用正则表达式,一个模式即可完成。这也是 easy-vibe 将正则基础放在“开发工具”附录(docs/es-es/appendix/2-development-tools/)中的原因:它是贯穿前端校验、后端数据清洗、日志分析、代码重构全流程的通用技能。

一句话理解:正则表达式 = 用特殊符号描述“你想找什么样的文本”\d表示数字,+表示一个或多个,所以\d+就是“一个或多个数字”。


2. 核心概念:像搭积木一样组合模式

正则的本质是用三类积木块组合出你想要的匹配模式。理解这三类积木,就等于掌握了正则 80% 的语法骨架。

2.1 积木块一:字符类(匹配什么字符)

字符类决定“匹配哪些字符”,是正则最基础的单元:

语法含义示例
.任意一个字符a.c→ abc、a1c、a c
\d数字 [0-9]\d\d→ 42、99
\w字母 / 数字 / 下划线\w+→ hello、user_1
\s空白字符匹配空格、制表符
[abc]集合中的任意一个[aeiou]→ 元音字母
[^abc]不在集合中的任意字符[^0-9]→ 非数字字符

从 easy-vibe 仓库的构建脚本中可以找到这三类最常用字符类的真实用法。例如 book-shared.mjs 用^\d+\.\d+\.\d+来识别语义化版本号:

const clean = (value) => String(value || '').trim().replace(/^v/, '') if (env && /^\d+\.\d+\.\d+/.test(env)) return env if (/^\d+\.\d+\.\d+/.test(ghRef)) return ghRef if (/^\d+\.\d+\.\d+/.test(tag)) return tag

这里\d+(一个或多个数字)与\.(转义后的点号)组合,精确锁定了x.y.z三段式版本号格式;/^v/则用字符类之外的普通字符字面量剥离版本号开头的v前缀。这说明即使是在构建系统这类基础设施代码中,\d\w\s也是最常被引用的字符类

2.2 积木块二:量词(匹配多少次)

量词决定“前面那个单元出现几次”:

语法含义示例
*0 次或多次ab*→ a、ab、abbb
+1 次或多次ab+→ ab、abbb(不匹配 a)
?0 次或 1 次colou?r→ color、colour
{3}恰好 3 次\d{3}→ 123
{2,4}2 到 4 次\d{2,4}→ 12、1234

量词是正则“一行模式解决问题”的威力来源:{n}精确计数、*/+/?表达“可有可无”或“重复多次”的模糊需求。例如判断“这位用户是否满足最低密码长度”时,{8,}就是“至少 8 位”的直接翻译(见 3.3 节)。

2.3 积木块三:位置与分组(在哪里匹配、怎么组织)

位置锚点与分组决定匹配发生的位置以及结果如何被组织:

语法含义示例
^行首^Hello→ 以 Hello 开头的行
$行尾end$→ 以 end 结尾的行
\b单词边界\bcat\b→ cat(不匹配 catch)
(...)捕获组(\d+)-(\d+)→ 分别捕获两部分
a\|bcat\|dog→ cat 或 dog

捕获组在“提取”场景中价值极高:不仅告诉你“匹配成功了”,还告诉你“匹配到的东西里每一部分各是什么”。easy-vibe 的发布脚本 book-shared.mjs 就用分组从 Git 仓库地址中提取作者与仓库名:

const sshMatch = repository.match(/github\.com:(.+?)\/(.+?)(\.git)?$/)

(.+?)是非贪婪捕获组(详见第 5 节),(\.git)?$是“可选的 .git 后缀 + 行尾锚点”,三组配合即可从 SSH 地址中分离出组织名、仓库名。\b单词边界则常用于“精确匹配整个词”而避免误伤子串(如cat匹配到catch内部)。


3. 实战:三组高频校验模式

以下三组模式来自原文档第 3 节,是开发中最常被复用的现成模式,建议直接收藏。

3.1 邮箱校验

[\w.+-]+@[\w-]+\.[\w.]+

逐段拆解:

  • [\w.+-]+— 用户名部分(字母、数字、点、加号、连字符),一个或多个;
  • @— 字面量 @ 符号;
  • [\w-]+— 域名部分;
  • \.— 转义后的点号;
  • [\w.]+— 顶级域名部分。

3.2 手机号校验(中国大陆)

1[3-9]\d{9}

逐段拆解:

  • 1— 以 1 开头;
  • [3-9]— 第二位数字为 3-9(覆盖当前主流号段);
  • \d{9}— 后接 9 位数字,共 11 位。

3.3 密码强度校验

^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$

逐段拆解:

  • (?=.*[a-z])— 至少包含一个小写字母(前瞻断言,只“看”不“消费”字符);
  • (?=.*[A-Z])— 至少包含一个大写字母;
  • (?=.*\d)— 至少包含一个数字;
  • .{8,}— 总长度至少 8 个字符;
  • ^$锚定整个字符串,确保断言作用于全文而非局部。

使用要点:正则表达式默认是“局部匹配”——只要文本中的某一段能匹配成功就算命中。因此在做格式校验时必须显式加上^...$(JS 中还可用match的全局匹配或 Python 的fullmatch)来锁定整段字符串;否则上面的密码模式可能放过“含 8 位以上子串但不满足整体要求”的输入。


4. 在代码中使用正则表达式

原文档给出 JavaScript 与 Python 两种主流语言的对照用法,下面完整继承并补充说明。

4.1 JavaScript

const text = '联系方式:13812345678 或 15099887766' const regex = /1[3-9]\d{9}/g const phones = text.match(regex) // ['13812345678', '15099887766'] // 替换:隐藏手机号中间四位 text.replace(/\d{4}(?=\d{4}$)/, '****') // 校验 /^[\w.+-]+@[\w-]+\.[\w.]+$/.test('user@example.com') // true

三个要点:

  • g标志(global):不加gmatch只返回第一个匹配;加g后返回全部匹配数组;
  • replace与前瞻(?=...)组合\d{4}(?=\d{4}$)匹配“后面紧跟末尾 4 位数字的那 4 位数字”,配合 replace 即实现“隐藏中间四位”而不影响最后四位,这正是前瞻断言“只看不消费”的典型生产用途;
  • .test():返回布尔值,适合放在表单校验分支中。

4.2 Python

import re text = '价格是 99 元,优惠 20 元' numbers = re.findall(r'\d+', text) # ['99', '20'] # 替换 re.sub(r'\d+', 'X', text) # '价格是 X 元,优惠 X 元' # 分组捕获 match = re.search(r'(\d+)-(\d+)', '2024-01-15') match.group(1) # '2024' match.group(2) # '01'

三个要点:

  • 原始字符串r'...':推荐始终使用原始字符串书写正则,避免\d\s等被 Python 字符串转义规则二次处理;
  • re.findall返回所有非重叠匹配的列表,是“提取全部”的主力 API;
  • match.group(n)按括号顺序访问捕获组,是“解析结构化文本”的入口。

5. 贪婪 vs. 懒惰:一个关键差异

看下面的经典场景:

文本:<b>hello</b> and <b>world</b>
模式匹配结果说明
<b>.*</b><b>hello</b> and <b>world</b>贪婪:尽可能多匹配
<b>.*?</b><b>hello</b>懒惰:尽可能少匹配

默认是贪婪模式——量词会尽量“吃”更多字符,直到无法继续扩展;在量词后追加?即切换为懒惰模式,匹配到第一个满足条件的位置就停止。绝大多数需要“逐条提取”的场景(如提取所有 HTML 标签、所有链接)都应当使用懒惰模式。

仓库脚本中同样随处可见这一原则的实战应用。例如 book-shared.mjs 解析 Vue 组件首标签时使用:

const openMatch = first.match(/^\s*<([A-Z][A-Za-z0-9_:-]*)\b/) const closeMatch = first.match(/^\s*<\/...>/)

而 HTML 代码块剥离(book-shared.mjs)采用[\s\S]*?这种“任意字符(含换行)懒惰匹配”来剔除<script><style><template>块:

.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, '\n') .replace(/<style\b[^>]*>[\s\S]*?<\/style>/gi, '\n')

提示:.默认不匹配换行符,所以跨行匹配常写成[\s\S]*?(空白 + 非空白 = 一切字符)或[\s\S]*

再如 generate-sitemap.mjs 用replace(/\.md$/, '')把 Markdown 路径转换为 URL 路径——\.md转义点号 +$行尾锚点,精确剥离扩展名;随后(generate-sitemap.mjs)用一串.replace(/&/g, '&amp;')等调用对 URL 做 XML 实体转义。这些例子说明:文本清洗、路径转换、HTML/XML 转义正是正则替换最主力的三大生产场景


6. 小结与速查

  1. 正则 = 描述文本模式的小型语言,用于查找、匹配与替换;
  2. 三类积木块:字符类(匹配什么)+ 量词(匹配多少次)+ 位置/分组(在哪里匹配、如何组织结果);
  3. \d\w\s是三大最高频字符类,覆盖数字、单词字符与空白;
  4. 不必从零编写:邮箱、手机号、密码等常见场景已有成熟模式可直接复用;
  5. 贪婪 vs. 懒惰:默认为贪婪(匹配更多),量词后加?变为懒惰(匹配更少)。

继续学习

  • 环境变量与 PATH 入门 — 理解系统配置
  • SSH 与密钥认证入门 — 安全连接远程服务器
  • 更多开发工具基础可回到 开发工具附录 总览

【免费下载链接】easy-vibe💻 vibe coding 101|The first course for AI-native product builders.项目地址: https://gitcode.com/GitHub_Trending/ea/easy-vibe

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

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

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

立即咨询