\_ 不是通配符,只匹配字面下划线;真正匹配任意单字符的是.(默认不匹配换行符),安全写法是[\s\S];\_ 在标准正则中无需转义,而.、*、?等元字符需转义才能表示字面意义。

正则中 _ 不是通配符,它就匹配下划线字符本身
很多人误以为 _ 在正则里像 * 或 ? 那样代表“任意字符”,其实不是。_ 是普通字符,只匹配字面量的下划线。真正匹配“任意单个字符”的是 .(英文点号),但要注意它默认不匹配换行符(\n)。
. 匹配任意字符时的常见陷阱
用 . 本意是“任意字符”,但实际行为受模式修饰符和上下文影响:
- 在 JavaScript 的
/.../字面量中,.默认不匹配\n、\r、\u2028、\u2029 - Python 的
re.match()或re.search()中,需显式传入re.DOTALL才让.匹配换行符 - 如果想“安全地匹配任意字符(含换行)”,更可靠的方式是用
[\s\S](匹配所有空白与非空白)或[\d\D]、[\w\W]
import re text = "line1\nline2" re.search(r"a.b", text) # None —— . 不跨行 re.search(r"a.b", text, re.DOTALL) # 匹配成功 re.search(r"a[\s\S]b", text) # 总是成功,无需 flag
下划线 _ 需要转义吗?什么时候必须加 \_
_ 在绝大多数正则引擎中**不需要转义**——它不在元字符列表里(元字符如 . ^ $ * + ? { } [ ] \ | ( ))。但在两种情况下你可能看到 \_:
- 某些老旧工具(如早期 grep 或部分 shell 环境)对非字母数字字符做保守转义,虽无害但冗余
- 写正则时混用了其他语言的语义(比如 SQL 的
_是单字符通配符),导致思维迁移错误 - 极少数正则方言(如某些数据库内置正则)把
_当作特殊符号,此时才需按文档确认是否转义
结论:标准 PCRE、JavaScript、Python re、Go regexp 中,_ 就是字面量,写 \_ 反而可能引发警告或兼容性问题。
真正需要转义的“看起来像通配符”的字符
容易被当成通配符但其实是元字符的,必须转义才能表示字面意义:
-
.→ 要匹配真实的小数点,写\. -
*→ 要匹配星号,写\* -
?→ 要匹配问号,写\? -
[、]、(、)、{、}、^、$、|、\—— 这些都需前置反斜杠
// JS 示例:匹配字符串 "price: $19.99"
const regex = /price: \$\d+\.\d{2}/;
"price: $19.99".match(regex); // ✅ 成功
"price: $19.99".match(/price: $.99/); // ❌ $ 是行尾锚点,. 是任意字符下划线本身从不扮演通配角色,真正易错的是把 . 当成万能字符却忽略它的换行限制,以及混淆不同语言中通配符的语义(比如 SQL 的 _ 和正则的 . 完全无关)。










