1. 概述

正则表达式(RegEx)是处理文本的强大工具,但并不是万能的。在某些场景下使用正则表达式不仅效率低下,甚至可能导致错误或难以维护。

本文将讨论哪些情况下应避免使用正则表达式,并介绍更合适的替代方案。

2. 当处理 HTML 或 XML 时

正则表达式适合处理形式语言(formal languages),但 HTML 和 XML 这类具有嵌套结构的标记语言并不适合用 RegEx 来解析。

一个常见的错误是尝试用正则表达式来提取或解析 HTML 内容。例如,有人可能会写一个 RegEx 来匹配 <div> 标签内的内容:

<div.*?>(.*?)</div>

但 HTML 是一棵结构复杂的树状结构(DOM),正则表达式无法有效跟踪嵌套层级和标签的闭合情况。

✅ 正确做法:使用专业的 HTML 解析库,如 Java 中的 Jsoup,或 XML 解析器如 SAX、DOM、StAX 等。

❌ 错误做法:尝试用 RegEx 解析 HTML/XML,最终容易“踩坑”。

3. 当简单搜索就足够时

有时候我们试图用正则表达式解决的问题其实用简单的字符串搜索就能搞定,而且更高效。

举个例子,假设我们想找出房子墙面的颜色:

house1

我们可以写一个匹配所有颜色名称的 RegEx:

(gr(a|e)y|white|black|blue|red|green|...)

但更简单的方式是先查找“color”关键词,再读取其附近的内容:

house2

✅ 正确做法:直接搜索关键词,避免过度使用 RegEx。

⚠️ 警告:RegEx 不应被用来处理这种“信息只出现一次”的问题,否则得不偿失。

4. 在对抗性环境中使用 RegEx

如果你在构建一个需要对抗用户输入的系统,比如:

  • 垃圾邮件过滤器
  • 脏话过滤器
  • 暗影封禁(shadow banning)

那么使用 RegEx 很容易被用户绕过。

举个例子:你写了一个 RegEx 来屏蔽含有“cars”的评论:

c(a|4)r

但用户可能会改用“automobile”、“four-wheeler”、“the thing that rolls”等替代说法。

✅ 正确做法:这类场景建议使用 NLP 技术或黑名单+白名单策略,而非依赖 RegEx。

❌ 错误做法:用 RegEx 对抗聪明的用户,只会让你的过滤器形同虚设。

5. 当布尔型 RegEx 永远为 false

正则表达式支持“或”(|)和“非”(?!)操作符,但不支持“与”(and)。虽然可以通过 De Morgan 定律 模拟“与”操作,但逻辑一旦复杂,RegEx 就可能永远返回 false。

例如:

(?!.*P|.*Q)

这个表达式表示“既不包含 P,也不包含 Q”,但如果逻辑太复杂,RegEx 可能会因为冲突永远无法匹配。

✅ 正确做法:避免在 RegEx 中使用复杂的布尔逻辑,尽量简化表达式。

❌ 错误做法:写出永远不匹配的 RegEx,导致逻辑错误。

6. 总结

正则表达式虽然强大,但在以下场景中应避免使用:

  • ✅ 解析 HTML/XML:应使用专用解析器
  • ✅ 简单文本搜索:直接使用字符串查找更高效
  • ✅ 对抗性输入处理:RegEx 易被绕过
  • ✅ 复杂布尔逻辑 RegEx:容易写出“永不匹配”的规则

📌 总结一句话:能不用正则就不用,能简单处理就不复杂化


原始标题:When Not to Use Regular Expressions?