想知道是否有人可以在PHP的preg_match函数中使用以下正则表达式失败的原因:-
$str = '\tmp\phpDC1C.tmp';
preg_match('|\\tmp\\([A-Za-z0-9]+)|', $str, $matches);
print_r($matches);
?>
尽管该模式似乎是有效的,但这仍导致错误消息" preg_match():编译失败:括号不匹配"。 我已经使用在线PHP正则表达式测试仪和Linux工具Kiki对其进行了测试。 似乎PHP正在转义左括号而不是反斜杠。
我已经解决了这个问题,方法是使用str_replace将反斜杠交换为正斜杠。 这适用于我的情况,但是很高兴知道为什么此正则表达式失败。
要对文字反斜杠进行编码,您需要对它进行两次转义:一次用于字符串,一次用于regex引擎:
preg_match('|\\\\tmp\\\\([A-Za-z0-9]+)|', $str, $matches);
在PHP中(使用单引号的字符串时),这仅与实际的反斜杠有关。 其他正则表达式转义也可以使用单个反斜杠:
preg_match('/\bhello\b/', $subject)
手册中对此进行了介绍(请参见页面顶部标有"注意:"的框)。
它用单引号引起来,是否真的有必要将其转义两次?
做得好,让我想起过去使用过的一些疯狂的正则表达式,例如 sed \\\\\\\\\\\\\\\\或类似的东西。
@Zombaya:是的,但前提是您尝试编码时使用实际的反斜杠。
我检查了手册及其真实内容。
php.net/manual/en/function.preg-quote.php吗?
您必须使用|\\\tmp\\\([A-Za-z0-9]+)|表达式
但是由于字符串的具体形式,所以有更好的方法来获取文件名。 例如:
substr($str, 5, -4);
考虑一下内存使用情况
我$ str的值只是一个例子。 在PHP中获取文件名值的最佳方法是使用pathinfo函数。
使用下一个正则表达式:
php >$str = '\tmp\phpDC1C.tmp';
php >preg_match('/[\\\\]tmp[\\\\]([A-Za-z0-9]+)/', $str, $matches);
php >print_r($matches);
Array
(
[0] => \tmp\phpDC1C
[1] => phpDC1C
)
奇怪的是,我刚刚使用您提到的同一台在线正则表达式测试仪进行了测试,并且编译时没有错误:
$ptn ="/
preg_match('|\\tmp\\([A-Za-z0-9]+)|', $str, $matches); print_r($matches); ?>;/";
$str ="";
preg_match($ptn, $str, $matches);
print_r($matches);
?>
抱歉,在我的问题中可能不清楚,但是在线工具接受它为有效,但是在我的实际代码中却失败了(即使使用该工具输出的代码)。 正则表达式应该有效。