d是预定义字符类,等价于[0-9],在php字符串中需写为"\d"或'd'才能正确传递给正则引擎;w不匹配中文,需u修饰符配合p{l};d和w是独立元字符,并非1和2的简写。d ↩w ↩

PHP正则中 d 是数字,不是“反斜线+d”字面量
很多人第一次看到 d 会下意识拆成「反斜线 + d」,以为要写成 \d 才对——这是错的。在 PHP 的 PCRE 正则里,d 是一个**预定义字符类**,代表「任意一个十进制数字」,等价于 [0-9]。它本身就是一个原子,不是需要手动转义的普通字符。
但注意:这个 d 出现在 PHP 字符串中时,PHP 解析器会先处理一次反斜线。所以你得写成 "\d"(双引号)或 'd'(单引号),才能让最终传给 preg_match() 的正则字符串里是真实的 d。
- 写
"d"→ PHP 把d当作未知转义,可能报 Warning 或静默丢弃反斜线,实际传过去的是d - 写
"\d"→ PHP 吃掉一个反斜线,剩下d交给正则引擎,正确匹配数字 - 写
'd'→ 单引号不解析转义,原样传d,也正确
w 包含字母、数字、下划线,不含汉字(默认模式)
w 在 PHP 的 PCRE 中默认等价于 [a-zA-Z0-9_],也就是「单词字符」——注意:它**不包含中文、日文、俄文字母等 Unicode 字符**,哪怕你在字符串里用了 UTF-8 编码。
如果你要匹配中文,不能靠 w,得显式写 [x{4e00}-x{9fff}] 或用 u 修饰符配合 p{Han}(需 PCRE2 支持)。
- 匹配英文+数字+下划线:
"/w+/"✔️ - 匹配「abc123_测试」中的前半部分:
"/w+/"只捕获abc123_,停在「测」字前 ❌ - 想含中文?加
u修饰符并改用p{L}:"/[p{L}p{N}_]+/u"✔️(p{L}是任意 Unicode 字母,p{N}是任意 Unicode 数字)
别把 D 和 W 当成「取反括号组」来记
D 不是 [^d] 的简写,而是独立元字符,语义是「匹配任意一个非数字字符」;同理 W ≠ [^w],它是「非单词字符」,即不在 [a-zA-Z0-9_] 范围内的任意单个字符(比如空格、逗号、中文、emoji 都算)。
关键差异在于:它们**仍然只匹配单个字符**,且不保证是「可见字符」——例如 D 会匹配换行符
、制表符 ,而你可能只想排除数字、保留空白。
- 想「匹配非数字但跳过空白」?别用
D,改用[^ds] - 想「匹配非单词字符但排除中文」?
W不够精确,得用[^a-zA-Z0-9_x{4e00}-x{9fff}]或更严谨的 Unicode 类 - 性能上:
D和W是引擎内置优化路径,比等价的否定字符组略快,但差别微乎其微,可读性优先
常见错误:在字符组 [] 里滥用 d 和 w
写 [dw] 看似合理,实则冗余甚至危险——因为 w 已经包含数字,d 完全被覆盖;更糟的是,某些旧版 PCRE 会把 d 在字符组里当作字面量 d 处理(尤其没开 u 时)。
字符组内,预定义元字符大多失去特殊含义,[d] 实际等价于 [d],不是「所有数字」。
- 正确写法:
[0-9a-zA-Z_]或直接用w(不在[]里) - 想加中文?
[0-9a-zA-Z_x{4e00}-x{9fff}],别塞d进去 - 例外:只有
、B、s、S、d、D、w、W在字符组里**有时仍有效**,但行为不统一,强烈建议避免
"[\d]+" 最终匹配的既不是数字也不是 d,而是取决于 PCRE 版本和修饰符——这种模糊地带,宁可展开写死,也不贪图缩写。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











