PHP正则中星号不是通配符,仅作用于前一个元素表示零次或多次匹配;独立非法,需转义*才匹配字面星号,. 默认贪婪且不跨行,惰性用.?,跨行需/s修饰符。

PHP正则里的星号 * 不是通配符,它只对紧挨着它前面的**单个元素**起作用,表示“匹配零次或多次”——这个限定范围和行为,跟 shell 中的 *(比如 ls *.txt)完全不同。
星号必须紧跟在某个可重复的元素后面
单独写 * 会报错:PREG_NO_ERROR 不触发,但 preg_match() 直接返回 false,且 preg_last_error() 返回 PREG_NO_ERROR 以外的错误码(常见是 PREG_INTERNAL_ERROR)。因为正则引擎无法解析“前面没东西的 *”。
-
/a*/合法:匹配"a"零次或多次,能匹配""、"a"、"aaa" -
/*a/非法:开头的*没有前置元素,PHP 报错 -
/(abc)*/合法:括号构成一个原子单元,*作用于整个(abc) -
/[0-9]*/合法:字符类[0-9]是一个元素,*表示数字可出现零次或多次
点星 .* 的实际含义和陷阱
. 匹配除换行符外的任意单字符,.* 组合起来不是“匹配任意字符串”,而是“匹配**尽可能多**的、不含换行符的字符”——这就是贪婪匹配。它常被误用为“通配占位符”,但会导致意外截断或过度匹配。
-
preg_match('/a.*b/', 'axxxb123b', $m)→ 匹配到"axxxb123b"(从第一个a到最后一个b),不是"axxxb" - 想停在第一个
b?得用惰性量词:/a.*?b/,其中?修饰*,让其“尽可能少匹配” - 要跨行匹配?得加
s修饰符:/a.*b/s,否则.跳过换行符,.*就断了
匹配字面意义的星号要用反斜杠转义
如果你真想匹配路径里那个 * 字符(比如 script*.sh),它在正则中是元字符,必须写成 *。注意 PHP 字符串里反斜杠本身要转义,所以双引号中写 "\*",单引号中写 '*'。
立即学习“PHP免费学习笔记(深入)”;
- 错误写法:
preg_match('/.*/', $path)—— 这是在匹配任意内容,不是找星号 - 正确找字面星号:
preg_match('/*/', $path)或preg_match('#*#', $path) - 匹配 Linux 路径中的通配部分(如
log_*.log)?别用正则模拟 shell glob;该用glob()函数
最容易被忽略的是:星号永远不独立存在,它永远依附于前一个 token;而绝大多数人初学时,第一反应是把它当 shell 通配符去套,结果 pattern 写出来根本跑不通,或者匹配出一堆意料之外的结果。



















