获取函数调用的第一个参数的字符串

时间:2013-01-21 11:50:30

标签: php regex

我想用PHP文件搜索特殊的函数调用。原因是,我想为GetText-Extension生成.MO-Files。所以我首先需要创建一个.PO文件,其中包含所有需要的文本字符串。

我已经找到了很多文字,但也有一些问题。

这是我的正则表达式找到函数调用的第一个参数:

/\_\([\'|\"]{1}(.+?[^\\\])[\'|\"]{1}[,]{0,1}.*?\)+/si

我需要找到具有以下模式的函数调用:

_("text");
_("text %s", 3);
_('text');

文本可能包含转义引号。如果有一个撇号或用于通话的正常报价,我的问题很明确,我需要知道。

如果我有电话

_('"text"');

然后我得到了问题,我得到了文本

"text

没有结尾引用。

你们有没有想法,我怎么能让我的正则表达式工作?

2 个答案:

答案 0 :(得分:4)

我会使用PHP的tokenizer来表示这种东西,而不是正则表达式:

$funcName = '_';
$tokens   = token_get_all(file_get_contents('path/to/your/script.php'));
$strings  = array();

foreach($tokens as $index => $token){

  if(!is_array($token))
    continue;

  if($token[0] === T_CONSTANT_ENCAPSED_STRING){

    if(!isset($tokens[$index - 2]) || ($tokens[$index - 1] !== "("))
      continue;

    list($id, $text, $line) = $tokens[$index - 2];

    // this is your string (substr drops quotes around it)
    if(($id === T_STRING) && ($text === $funcName))
      $strings[] = substr($token[1], 1, -1);

  }    
}

var_dump($strings);

答案 1 :(得分:2)

原始正则表达式:

_\((?|'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")

分隔正则表达式:

~_\((?|'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")~

结果是捕获组1.我使用了分支重置模式(?|pattern),以便为每个由|分隔的交替分支重置捕获组编号。

分支内部重置(?|'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")是2模式:

  • '((?:[^'\\]|\\.)*)':匹配并捕获单引号字符串中的内容,该字符串由非引号 - 非反斜杠或转义序列组成。实际上,我在这里有点粗心,因为(原始)新行字符被认为是字符串的一部分。我不认为规范会允许这样做,但如果输入包含有效代码,那么应该没有问题。

  • "((?:[^"\\]|\\.)*)":与上面相同,但是对于双引号字符串。

请注意,我不会使用该函数的其余参数。