Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 获取函数调用的第一个参数的字符串_Php_Regex - Fatal编程技术网

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

Php 获取函数调用的第一个参数的字符串,php,regex,Php,Regex,我想用PHP文件搜索一个特殊的函数调用。原因是,我想为GetText扩展名生成.MO文件。所以我首先需要创建一个.PO文件,其中包含所有需要的文本字符串 我已经找到了很多文本,但是有一些问题 下面是查找functioncall的第一个参数的正则表达式: /\_\([\'|\"]{1}(.+?[^\\\])[\'|\"]{1}[,]{0,1}.*?\)+/si 我需要找到具有以下模式的函数调用: _("text"); _("text %s", 3); _('text'); 文本可以包含转义引号

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

我已经找到了很多文本,但是有一些问题

下面是查找functioncall的第一个参数的正则表达式:

/\_\([\'|\"]{1}(.+?[^\\\])[\'|\"]{1}[,]{0,1}.*?\)+/si
我需要找到具有以下模式的函数调用:

_("text");
_("text %s", 3);
_('text');
文本可以包含转义引号。我的问题是尖锐的,我需要知道,如果有一个撇号或一个正常的引用用于调用

如果我有电话

_('"text"');
然后我得到了问题,我得到了文本

"text
没有结尾的引语

你们有谁知道如何让我的正则表达式工作吗?

原始正则表达式:

_\((?|'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")
分隔正则表达式:

~_\((?|'((?:[^'\\]|\\.)*)'|"((?:[^"\\]|\\.)*)")~
结果是捕获组1。我使用了分支重置模式
(?|模式)
,以便为每个由
|
分隔的交替分支重置捕获组编号

分支内部的重置
(?|'(?:[^'\]\\\\.*))“\\\”((?:[^'\]\\\.*)”)
是两种模式:

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

  • “(((?:[^“\\]\\)*)”
    :同上,但用于双引号字符串

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

我将使用PHP来处理此类内容,而不是正则表达式:

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

您不使用xgettext程序收集字符串的具体原因是什么?您的正则表达式似乎无效。我已经有了一个包含模板文本的DB。还有一个翻译文本的工具。这就是为什么我想用这个工具完成所有的工作,还有PHP文本。它实际上工作得很好,我只是对“text”字符串有一个问题。。你会改进什么,或者哪些是无效的?:)实际上效果很好,但是当我有字符串“hallo text”时,它在\之后被拆分,现在似乎效果很好。但我得到了错误“编译失败:缺少终止]字符类在偏移量51英寸..”,所以我增加了两个反斜杠。它知道看起来是这样的:preg\u match\u all(“~”((?)\”((?:[^\\\].\)*)\“。”((?:[^\].\\)*))”,…)@Kevingleer:啊,既然你需要将正则表达式放入一个字符串中,你就需要相应地进行转义。但是你试过其他解决方案吗?它比正则表达式可靠得多。是的,我现在试过了,它看起来更干净,我会更好地使用它,因为它必须更可靠。但是谢谢你的正则表达式;)@KevinGlier:很高兴PHP内置了lexer,而且非常容易使用。很高兴学习了一些新的东西:)+1以获得更干净的解决方案,但我想知道为什么不以函数名而不是字符串开始。没有理由,只是我的选择。