preg_match_all()匹配错误

时间:2014-09-26 11:04:22

标签: php regex yii

我正在尝试在Yii项目中修复某段代码。我记得你没记过。

它的作用是试图找到所有出现的

Yii::t('category', 'message')
Yii::t('category', 'message', some_more_stuff)

两者都有双引号和单引号。它从中提取类别和键(它是i18n函数)。

然而,它在诸如

之类的事情上失败了
Yii::t('moo', $a ? 'baa', 'oink')

然后它一直匹配,直到下一个Yii :: t()出现 - 可能是正则表达式中的一些小故障,但我试图将它带入正则表达式调试器并且它工作正常。

以下是代码示例。如果你可以修复它只匹配第二个Yii :: t(),那就太棒了。我试过但是无法正常工作。

<?php

// prepare an example (in real, uses file_get_content)
$subject = <<<FOO
<?php
    \$ONOFF_TEXT = Yii::t('manage', \$on ? 'on' : 'off');
?>
<a title="<?= Yii::t('manage', 'btn_manual') ?>"></a>
FOO;

// find matches
$n = preg_match_all(
    '/\s*\(\s*(\'.*?(?<!\\\\)\'|".*?(?<!\\\\)")\s*,\s*(\'.*?(?<!\\\\)\'|".*?(?<!\\\\)")\s*[,\)]/s',
    $subject, $matches, PREG_SET_ORDER);

// iterate over matches
for($i = 0; $i < $n; ++$i) {
    $category = $matches[$i][1];
    $message = $matches[$i][2];
    echo("MESSAGE: $category -----> $message\n");
}

我得到了什么:

MESSAGE: 'manage', $on ? 'on' : 'off');
?>
<a title="<?= Yii::t('manage' -----> 'btn_manual'

我应该得到什么:

MESSAGE: 'manage' -----> 'btn_manual'

1 个答案:

答案 0 :(得分:1)

只需将第一个捕获组中的.*?更改为[^\n]*

\bYii::t\s*\(\s*(\'[^\n]*?[^\\\\]\'|".*?[^\\\\]")\s*,\s*(\'.*?[^\\\\]\'|".*?[^\\\\]")\s*[,\\)]

DEMO

\bYii::t\s*\(\s*(\'[^\n](?:(?!Yii::t).)*[^\\\\]\'|".*?[^\\\\]")\s*,\s*(\'.*?[^\\\\]\'|".*?[^\\\\]")\s*[,\\)]

DEMO