/^key=[^=]*$/
key=valuekey=key=42key=on·key=a=bkeyvaluek=v
灾难性回溯:正则表达式为什么会卡死
一个 7 个字符的正则,在 30 个字符的输入上可能要跑好几秒,在 40 个字符的输入上可能要跑几个小时。本文讲解回溯的原理、(a+)+ 这类嵌套量词为什么会爆炸、它在 Stack Overflow 和 Cloudflare 引发的故障,以及让正则变安全的改写方法。
Regex Hunter/blog/ · 狩猎手记
/^key=[^=]*$/
key=valuekey=key=42key=on·key=a=bkeyvaluek=v
一个 7 个字符的正则,在 30 个字符的输入上可能要跑好几秒,在 40 个字符的输入上可能要跑几个小时。本文讲解回溯的原理、(a+)+ 这类嵌套量词为什么会爆炸、它在 Stack Overflow 和 Cloudflare 引发的故障,以及让正则变安全的改写方法。
Regex Hunter/^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/
2026-10-131999-12-312000-01-012026-02-28·26-10-132026/10/132026-1-313-10-2026
括号有两项工作:分组和捕获。本文介绍非捕获组 (?:…) 如何只分组不捕获,命名组 (?<year>…) 如何让捕获内容更易读,如何用 \k<name> 引用它们,以及 Python 里的写法。
Regex Hunter/^colou?r$/i
colorColourCOLORcolour·colrcoloursdiscolorkolor
每个 JavaScript 正则修饰符会改变什么,附可交互示例:忽略大小写 i、全局 g(以及 lastIndex 陷阱)、多行 m、dotAll s、Unicode u、粘性 y 和索引 d,还有 Python 中对应的写法。
Regex Hunter/^\d{5}$/
90210100010213960614·9021902100ZIP 9021090210-1234
^ 和 $ 匹配的不是字符,而是位置。为什么没有锚点的正则检查得比你想的少,m 修饰符改变了什么,Python 的 $ 如何对待末尾的换行符,以及什么时候该改用 \A 和 \z。
Regex Hunter/^[A-Z][a-z]+$/
ParisLimaOsloRome·parisPARISNew YorkR2D2
字符类是正则中最常用的部分,也最容易出现不易察觉的错误。本文讲解 [abc]、[a-z]、[^…]、\d、\w 和 \s 到底匹配什么,以及它们背后的陷阱:[A-z]、放错位置的连字符、方括号里的点,以及不是 0 到 9 的数字。
Regex Hunter/<.+?>/
<b></i><br>·bi><>
正则表达式的量词会尽可能多地抓取文本。本文讲清贪婪匹配和懒惰匹配到底如何工作,为什么 <.+> 会吞掉一整行 HTML,以及什么时候否定字符类比两者都好用。
Regex Hunter今日棋盘已上线
抓住每个怪物,放过每个无辜者——字符越少越好。