I have a confession that will make regex purists wince: for the first few years of my career, which I wrote-pasting from Stack Overflow, change one character, running the code, see it failed, and repeating until it happen to work。i did't understanding the patterns - I bullyed them into submit。it was slow, and wereaser, the patterns I shipped were fragile in ways I can't see。
What fixed that wasn't阅读理论(尽管我最终做到了),它是一个视觉测试仪- 一个我键入图案的盒子,一个我粘贴测试字符串的盒子,匹配点亮了我改变某事的瞬间我可以 看见 为什么 \d+ grabed超过我想要的,或者为什么我的电子邮件模式拒绝了一个完全有效的地址,regex不再是一个猜谜游戏,变成了一个紧密的反馈循环。
那's正是什么 正则表达式构建器 toolz。dev上就是。你写一个模式, 掉落测试数据, 切换标志, 实时观看匹配和捕获的组突出显示。它完全在你的浏览器中运行, 所以日志行或用户数据你're测试反对永远不会上传到任何地方。本指南是regex参考我希望I'd当年有 - 我实际重用的模式, 完整的速查表, 以及一个错误, 可以打倒生产服务器。
TL;博士: 将您的图案和测试字符串粘贴到 正则表达式构建器 并切换
g/i/mflags来查看匹配突出显示live。start简单,添加约束来杀死误报,测试对抗输入以避免灾难性的回溯,对于提取的数据,将其与the json格式化程序 並 Base64 转换器。所有客户端,全部免费。
正则表达式到底是什么?
正则表达式 - regex 或 regexp - 是一个描述搜索模式的紧凑字符串。而不是"找到cat这个词,"你可以说"找到任何五位数的数字," "找到任何看起来像电子邮件的东西,"或者"找到以ERROR开头的每一行。"几乎每种语言和编辑器都支持它们,这就是使该技能如此便携的原因:学习一次,然后在JavaScript、Python、你的 grep并且您的 IDE's 查找并替换。
20世纪50年代,这个概念来自形式语言理论,肯 · 汤普森在20世纪60年代将其连接到计算中进行文本编辑。那个历史很重要,有一个实际原因I'll回到:"regular"语言有限制,这就是为什么regex真的是不能解析像HTML这样的嵌套结构,无论你多么聪明。
I在正常的一周内到达regex的地方:在用户输入到达数据库之前验证用户输入,从非结构化日志行中提取字段,在整个代码库中进行查找和替换,平搜索可以't表达,并在迁移过程中过滤数据 正则表达式构建器 是我在接近真实代码之前对每一个进行原型设计的地方。
以下是基本构建块 - 您从以下位置组装图案的字母表:
| 语法 | 意义 | 例子 | 比赛 |
|---|---|---|---|
. |
除换行符外的任何字符 | h.t |
帽子,热,打 |
\d |
任何数字 (0-9) | \d{3} |
123、456 |
\w |
字字符(az,az,0-9,_) | \w+ |
你好,测试_123 |
\s |
任何空白 | hello\sworld |
你好世界 |
^ |
字符串的开始 | ^Hello |
一开始你好 |
$ |
字符串结束 | end$ |
结束于结束 |
* |
零或更多 | ab*c |
ac、abc、abbc |
+ |
一个或多个 | ab+c |
美国广播公司,美国广播公司 |
? |
零或一 | colou?r |
颜色,颜色 |
{n} |
正好是n次 | \d{4} |
2026年 |
{n,m} |
n和m之间 | \d{2,4} |
12、123、1234 |
[abc] |
角色类 | [aeiou] |
任何元音 |
[^abc] |
被否定的阶级 | [^0-9] |
任何非数字 |
(...) |
捕获组 | (hello) |
捕获"你好" |
a|b |
交替(或) | cat|dog |
猫或狗 |
每个开发人员都应该方便使用哪些 Regex 模式?
I've测试的,这些都是,坏了,修复了,现在保存在个人片段文件中。直接复制到 正则表达式构建器 并向他们扔自己的边缘盒子。
电子邮件(实用的那种)
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
这匹配 [email protected] 並 [email protected]的,而拒绝 @example.com 或 user@com。这里's重要的诚实,虽然:完整的电子邮件语法在 RFC 5322 是极其复杂的- 它在技术上允许引用字符串和评论几乎没有人使用。Don't 追逐 100% RFC 合规性与正则表达式。将实用的 99% 与上面的模式相匹配,然后通过发送验证电子邮件确认地址是真实的。那's 我最看到的错误:团队在"airtight"上燃烧日子,仍然可以't 从错字中告诉真实的收件箱。
网址
^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&\/=]*)$
比赛 https://toolz.dev 並 http://www.example.com/path?query=value;拒绝 ftp://... 和纯文本。
美国电话号码
^(\+1)?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$
足够灵活 555-123-4567、 (555) 123-4567、 +1 555.123.4567、和 5551234567。
IPv4 地址
^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$
嵌套交替强制每个八位字节保持在 0 be255 中,因此它正确拒绝 999.999.999.999。
强密码检查
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$
需要至少 8 个带有小写、大写、数字和符号的字符。 (?=...) lookaheads每个断言一个条件而不消耗字符 - 一个整齐的伎俩值得理解。
ISO 日期 (YYYY-MM-DD)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
比赛 2026-07-11,拒绝 2026-13-01 並 2026-02-32。
六角色
^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$
比赛 #4466EE、 #abc、 #000000。
Regex 速查表
保持这个固定。 It's是我检查最多的参考。
锚
| 图案 | 描述 |
|---|---|
^ |
串(或多行模式下的行)的开始 |
$ |
串(或多行模式下的行)的末尾 |
\b |
词边界 |
\B |
非词边界 |
量词
| 图案 | 描述 |
|---|---|
* |
0以上(贪婪) |
+ |
1个或更多(贪婪) |
? |
0或1(贪婪) |
*? +? ?? |
懒惰版本 - 尽可能少地匹配 |
{n} {n,} {n,m} |
n 和 m 之间恰好是 n /n 或更多/ |
角色类别
| 图案 | 描述 |
|---|---|
[abc] |
a、b 或 c |
[^abc] |
不是 a、b 或 c |
[a-z] [A-Z] [0-9] |
范围 |
\d \D |
数字/非数字 |
\w \W |
单词字符/非单词字符 |
\s \S |
空白/非空白 |
团体和环顾四周
| 图案 | 描述 |
|---|---|
(abc) |
捕获组 |
(?:abc) |
非捕获组 |
(?<name>abc) |
名为捕获组 |
(?=abc) / (?!abc) |
正/负的前瞻 |
(?<=abc) / (?<!abc) |
正/负背后 |
旗帜
| 旗 | 描述 |
|---|---|
g |
全局 - 查找所有匹配项 |
i |
区分大小写 |
m |
多行线 - ^ 並 $ 匹配线边界 |
s |
点数- . 匹配换行符 |
u |
Unicode 支持 |
如何在不损失一个小时的情况下构建和调试模式?
我的过程故意无聊,因为无聊是可以重复的:
- 从与一个真实示例匹配的最简单的事情开始。 Don't 尝试一次处理每一个案件。
- 粘贴阳性和阴性测试字符串 进入 正则表达式构建器- 应该匹配的事情和不应该匹配的事情。
- 收紧以杀死误报。 添加锚点 (
^、$) 所以模式与整个字符串匹配,并交换.对于特定的类,例如[a-z]或[^,]。 - 向其投掷对抗性输入- 空字符串、巨量输入、Unicode 和字面正则表达式字符作为数据。
- 只有这样才能优化。
事不端时,它's几乎总是三件事之一,如果 匹配太多的, 你的量词贪婪 - 让它们懒惰 (*?)或者你的课更具体。如果它 匹配太少,你可能需要 i flag或者忘记逃避一个特殊角色,如果 根本不匹配的, 检查未转义的元字符 (.、 *、 +、 (、 [、 {等)意味着是字面上的,或者是隐形的字符,比如隐藏在测试字符串中的选项卡。
什么是灾难性的回溯?为什么你应该害怕它?
I'd纹身新开发者如果可以的话,这是部分,早些时候我发货了一个输入验证正则表达式,看起来完全无辜,一个下午,一个请求将CPU核心固定为100%,并保持模式是问题所在。
Regex引擎能't找到匹配项时,它 回溯-它退缩, 尝试其他方式来满足模式, 某些形状使路径的数量呈指数级爆炸, 课本例:
^(a+)+$
像这样的输入 aaaaaaaaaaaaaaaaaaaab (一连) a a结尾 b),嵌套量词为发动机提供了天文数字的划分方法 as,它都尝试了在结束"不匹配。"之前你的应用程序冻结了。这是一个真正的拒绝服务类,称为 雷多斯 (常规表达拒绝服务),并且攻击者确实利用了它。
如何保持安全:
- 永远不要嵌套量词。
(a+)+、(a*)*、和(a+)*是危险信号。 - 使用原子群或所有格量词 发动机支撑它们的地方:
(?>a+)或a++。 - 要具体。
[a-z]+回溯小于.+因为它探索的路径较少。 - 锚定您的图案 因此,发动机在不匹配的输入下会快速失效。
- 使用几乎匹配但最终失败的字符串进行测试- that's 回溯的最坏情况。
如果你're on Go,这个问题根本不存在't,这让我进入下一节。
Regex 在语言之间有何不同?
核心语法行得好,细节咬人 这些是差异 I've居然被绊倒了。
JavaScript:
const regex = /\d{3}-\d{4}/g;
const pattern = new RegExp('\\d{3}-\\d{4}', 'g'); // note the doubled backslashes
'555-1234'.match(regex); // ["555-1234"]
const m = '2026-07-11'.match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/);
m.groups.year; // "2026"
小心:lookbehind 刚刚抵达 ES2018, \d 仅匹配 ASCII 数字,并且 g 旗帜制作 .test() 有状态通过 lastIndex- 循环中的微妙错误源。
Python:
import re
pattern = re.compile(r'\d{3}-\d{4}') # raw strings avoid double-escaping
pattern.findall('Call 555-1234 or 555-5678') # ['555-1234', '555-5678']
始终使用原始字符串 (r'...')。记住 re.match 仅在开始时使用锚点 re.search 去任何地方寻找。和 re.VERBOSE 让您编写多行注释模式,这是复杂模式的救星。
PHP: 模式需要分隔符('/\d{3}-\d{4}/'),它使用强大的PCRE引擎,并且 preg_match 返回 1、 0、或者 false 错误时 - 所以请检查一下 ===。
去: RE2引擎使用,这是故意的 删除前瞻、后瞻和反向参考 换取线性时间匹配的保证。这意味着甚至不可能发生灾难性的回溯--当您选择一种用于不受信任输入匹配的语言时,这是一个真正不同的权衡,值得了解。
真实示例:解析 Apache 日志行
Here's regex真的是很棒的东西,一个标准的Apache访问日志线看起来像:
192.168.1.1 - frank [11/Jul/2026:10:27:10 -0500] "GET /api/users HTTP/1.1" 200 1234
这种模式将其拉开:
^(\S+) \S+ (\S+) \[([^\]]+)\] "(\S+) (\S+) (\S+)" (\d{3}) (\d+)$
将两者粘贴到 正则表达式构建器 每个捕获的组分别点亮:
| 集团 | 内容 | 例子 |
|---|---|---|
| 1 | IP地址 | 192.168.1.1 |
| 2 | 用户名 | 弗兰克 |
| 3 | 时间戳 | 2026 年 7 月 11 日:10:27:10 -0500 |
| 4锛屽湪娴欐睙鏉 | HTTP 方法 | 得到 |
| 5锛屽湪娴欐睙鏉 | 请求路径 | /api/用户 |
| 6 | HTTP 版本 | HTTP/1.1 |
| 7 | 状态代码 | 200 |
| 8 | 响应大小 | 第1234章 |
一旦小组在测试仪中排队,将其转换为 a re.findall 在 Python 或 a 中 match() javascript 中是微不足道的 - 你已经知道它有效。
常见问题
什么是正则表达式构建器?
Regex builder是一个交互式工具,你键入一个正则表达式,并立即看到它与测试字符串匹配,匹配和捕获的组突出显示,它用一个实时代码替换了代码中缓慢的写-运行-失败-重写循环 正则表达式构建器 在 toolz。dev 上,这完全是在您的浏览器中完成的,因此测试数据会保留在您的计算机上。
每种编程语言中的正则表达式模式是否相同?
核心语法几乎相同,但细节差异足以导致错误。较旧的 JavaScript 缺乏 lookbehind,Go's RE2 引擎根本没有前瞻性或反向引用,Python 将组命名为 (?P<name>...) 在某些情况下。始终确认您're 语言中的模式实际上是针对性的,而不是假设可移植性。
如何使用 regex 验证电子邮件地址?
使用类似的实用模式 ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$的,处理绝大多数真实地址,不要尝试在正则表达式中完全符合RFC 5322 - 语法太复杂了,你'll仍然拒绝有效地址或接受错别字。将正则表达式与验证电子邮件配对以确认收件箱实际存在。
为什么我的正则表达式会冻结应用程序?
几乎总是灾难性的回溯。具有嵌套量词的模式,例如 (a+)+ 当匹配路径满足几乎匹配但最终失败的输入时,创建指数数量的匹配路径,并且引擎会尝试所有这些。删除嵌套量词,更喜欢特定的字符类 .+的,并添加锚,这样发动机就可以快速失效。
我可以使用正则表达式来解析 HTML 或 JSON 吗?
不,不适用于任何超出琐碎提取的内容。 HTML 和 JSON 不是常规语言 - 它们允许正则表达式根本无法跟踪的任意嵌套。使用真实解析器:DOMParser 或 Cheerio for HTML,以及 JSON.parse 或者 JSON 的 JSON 工具。Regex 是矩结构嵌套的错误工具。
What's 贪婪与懒惰搭配的区别?
贪婪的量词(*、 +、 ?)尽可能多地抓取,如果需要则回溯;懒惰的(*?、 +?、 ??)尽量少抓,只有在被迫的情况下才扩大。反对 <b>bold</b>的,贪婪的 <.*> 懒惰地吞下整根绳子 <.*?> 一开始就停下来 <b>.选择正确的往往是模式匹配过多时的解决办法。
如何逃避正则表达式中的特殊角色?
在您字面意思的任何元字符前面加上反斜杠: \.、 \*、 \+、 \?、 \(、 \)、 \[、 \]、 \{、 \}、 \^、 \$、 \|、和 \\。大多数语言还提供一个帮助者来为您逃脱整个字符串 - re.escape() python 中,例如 - 这比字符串来自用户输入时用手转义更安全。
正则表达式标志 g、i 和 m 是什么意思?
g (全局)找到每场比赛,而不是在第一场停止, i (忽略大小写)使模式大小写不敏感,并且 m (多重线)使 ^ 並 $ match在每一个换行而不是只有字符串's开始和结束。它们自由组合,所以 gim do all three。JavaScript 中经常出现的 gotcha:重用 a g regex 跨越呼叫 lastIndex 在他们之间,这使得 test() 替代真假 - 重新创建模式或重置 lastIndex。
正则表达式的前瞻是什么?
A lookehead断言,某件事做或不做't跟随,而不消耗它。 foo(?=bar) 匹配 foo 仅当 bar 接下来; foo(?!bar) 仅当它不匹配时才匹配't。看后面的((?<=...)、 (?<!...))向后做同样的事情,并登陆了现代的JavaScript,Python和PCRE - 但没有登陆Go's RE2,它完全拒绝了这两个密码规则是经典用途: ^(?=.*\d)(?=.*[a-z]).{8,}$ 堆叠断言,以便在同一位置独立检查每个要求。
如何将电话号码与正则表达式匹配?
对于特定的格式,要明确而不是聪明: ^\(\d{3}\) \d{3}-\d{4}$ 匹配 (555) 123-4567.为了容忍各种分离器,允许可选的,如 ^\+?1?[-.\s]?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}$。电话号码在不同国家/地区都很混乱,因此在存储之前仅验证您实际接受的格式并将其标准化为数字 - 在信任模式之前实时构建和测试模式。
包裹起来
Regex从我最可怕的技能变成了我最常用的那一刻,我开始在实时测试仪中构建模式,而不是在编辑器中进行猜测。开始简单,测试真实和对抗性的输入,尊重灾难性的回溯,并保留一个你信任的模式的个人库。
的 正则表达式构建器 on toolz。dev 使该循环快速,具有实时匹配、分组突出显示和标志切换功能 - 所有这些都在您的浏览器中运行,因此您的测试数据将保持私密性。当您的模式提取 JSON 时,将其交给 json格式化程序;当它捕获 Base64 blob 时,用 the 解码 Base64 转换器。 或浏览所有 600 多个免费工具,网址为: Toolz.dev。



