【问题标题】:"preg_match(): Compilation failed: unmatched parentheses" in PHP for valid pattern“preg_match():编译失败:括号不匹配”在 PHP 中用于有效模式
【发布时间】:2012-05-10 05:18:27
【问题描述】:

想知道是否有人可以解释为什么在 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 Regular Expression tester 和 Linux 工具 Kiki 对其进行了测试。似乎 PHP 正在转义左括号而不是反斜杠。

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

【问题讨论】:

    标签: php regex preg-match


    【解决方案1】:

    使用下一个正则表达式:

    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
    )
    

    【讨论】:

      【解决方案2】:

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

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

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

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

      the manual 对此进行了介绍(请参阅页面顶部标有“注意:”的框)。

      【讨论】:

      • 用单引号括起来,真的有必要转义两次吗?
      • 干得好,让我想起了我过去使用过的一些疯狂的正则表达式,例如sed /\\\\\\\/\\\\\\\\\/ 或类似的东西。
      • @Zombaya:是的,但前提是它是您尝试编码的实际文字反斜杠。
      • 我检查了manual,这是真的。
      【解决方案3】:

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

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

      substr($str, 5, -4);
      

      考虑内存使用情况

      【讨论】:

      • 我的 $str 的值只是一个例子。在 PHP 中获取文件名值的最佳方法是使用 pathinfo 函数。
      【解决方案4】:

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

      <?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);
      ?>
      

      【讨论】:

      • 对不起,我的问题可能不清楚,但在线工具接受它为有效,但它在我的实际代码中失败(即使使用工具输出的代码也是如此)。正则表达式应该是有效的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-17
      相关资源
      最近更新 更多