13

想知道是否有人可以解释为什么在 PHP 的 preg_match 函数中使用以下正则表达式会失败:-

<?php
$str = '\tmp\phpDC1C.tmp';

preg_match('|\\tmp\\([A-Za-z0-9]+)|', $str, $matches);

print_r($matches);
?>

这会导致错误消息“preg_match(): Compilation failed: unmatched parentheses”,尽管模式似乎是有效的。我已经使用在线PHP 正则表达式测试器和 Linux 工具 Kiki 对其进行了测试。似乎 PHP 正在转义左括号而不是反斜杠。

我通过使用 str_replace 将反斜杠换成正斜杠来解决这个问题。这适用于我的情况,但很高兴知道为什么这个正则表达式会失败。

4

4 回答 4

20

要对文字反斜杠进行编码,您需要对其进行两次转义:一次用于字符串,一次用于正则表达式引擎:

preg_match('|\\\\tmp\\\\([A-Za-z0-9]+)|', $str, $matches);

在 PHP 中(使用单引号字符串时),这仅与实际的反斜杠相关;其他正则表达式转义可以使用单个反斜杠:

preg_match('/\bhello\b/', $subject)

这在手册中有介绍(请参阅页面顶部标有“注意:”的框)。

于 2012-04-30T13:55:53.293 回答
1

你必须使用|\\\tmp\\\([A-Za-z0-9]+)|表达式

但是由于字符串的具体形式,有更好的方法来获取文件名。例如:

substr($str, 5, -4);

考虑内存使用情况

于 2012-04-30T14:01:36.317 回答
0

使用下一个正则表达式:

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
)
于 2012-04-30T14:24:47.493 回答
0

奇怪的是,我刚刚使用您提到的相同在线正则表达式测试器进行了测试,并且编译时没有错误:

<?php 
$ptn = "/<;?php $str = '\tmp\phpDC1C.tmp'; 
preg_match('|\\tmp\\([A-Za-z0-9]+)|', $str, $matches); print_r($matches); ?>;/";
$str = "";
preg_match($ptn, $str, $matches);
print_r($matches);
?>
于 2012-04-30T13:56:04.773 回答