Php 如何优化这个正则表达式

Php 如何优化这个正则表达式,php,regex,Php,Regex,有人能帮我优化我的正则表达式模式吗,这样我就不必遍历下面的每个正则表达式了。所以它匹配所有字符串,就像我提供的示例一样 $pattern = "/__\(\"(.*)\"/"; preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); $pattern = "/__\(\"(.*)\",/"; preg_match_all($pattern, $content, $matches, PREG_SET_ORDER); $patt

有人能帮我优化我的正则表达式模式吗,这样我就不必遍历下面的每个正则表达式了。所以它匹配所有字符串,就像我提供的示例一样

$pattern = "/__\(\"(.*)\"/";
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);

$pattern = "/__\(\"(.*)\",/";
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);

$pattern = "/__\(\'(.*)\'/";
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);

$pattern = "/__\(\'(.*)\',/";
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);

$pattern = "/_e\(\"(.*)\"/";
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);

$pattern = "/_e\(\"(.*)\",/";
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);

$pattern = "/_e\(\'(.*)\'/";
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);

$pattern = "/_e\(\'(.*)\',/";
preg_match_all($pattern, $content, $matches, PREG_SET_ORDER);
例如:

_e('string');
_e("string");
_e('string', 'string2');
_e("string", 'string2');
__('string');
__("string");
__('string', 'string2');
__("string", 'string2');
如果可能,也要匹配下面的这些字符串

"string"|trans
'string'|trans
"string"|trans({}, "string2")
'string'|trans({}, 'string2')
'string'|trans({}, "string2")
"string"|trans({}, 'string2')
如果有可能也得到string2的值。在最坏的情况下,文件中还混合了单引号和双引号

就像你现在在我的preg_match_all代码中看到的,我用8个模式作为第一个模式,也用8个模式作为第二个模式来获得第一个字符串

注: 我只是在控制台命令上运行这个脚本,而不是在PHP应用程序中运行。所以我对表演一点也不在意,也没关系

谢谢你的帮助

编辑

谢谢你的回复。我都试过了你的正则表达式,快到了。我的问题可能令人困惑。我不会说英语。我从regex101复制粘贴。这可能更容易理解,我正在努力实现的目标

还有这个


请看这个。我试着从wordpress项目和使用trans filter的细枝文件中提取翻译。我知道有mo-po编辑器,但编辑器无法识别我使用的文件扩展名。

我冒昧地用JavaScript编写了这篇文章,但正则表达式也可以使用

我的完整代码如下所示:

const r = /^_[e_]\((\"(.*)\"|\'(.*)\')(, (\"(.*)\"|\'(.*)\'))?\);$/;

const xs = [
  "_e('string');",
  "_e(\"string\");",
  "_e('string', 'string2');",
  "_e(\"string\", 'string2');",
  "__('string');",
  "__(\"string\");",
  "__('string', 'string2');",
  "__(\"string\", 'string2');",
];

xs.forEach((x) => {
  const matches = x.match(r);

  if(matches){
    console.log('matches are:\n ', matches.filter(m => m !== undefined).join('\n  '));
  }else{
    console.log('no matches for', x);
  }
});
^(\"(.*)\"|\'(.*)\')\|trans\(\{\}, (\"(.*)\"|\'(.*)\')\))?$
现在让我解释一下正则表达式是如何工作的,以及我是如何实现它的: 首先,我注意到所有字符串都以u开头,以;, 所以我知道正则表达式必须看起来像^…\;$。 此处^和$标记字符串的开头和结尾,如果不需要,则应将其省略

在首字母“youhaveother”或“e”之后,我们把它们放在一个组中,后面跟着左括号:[e\]\

现在我们有了一个in或in'的字符串,我们把它作为替代项记下:\.\\\'.\'.\''.\'

重复此字符串,但也可以选择在前面加一个前导。 那么我们得到了…?对于可选部分,以及整个第二部分的\.\\\\'.\\\

对于问题的第二部分,您可以使用相同的策略:

"string"|trans
'string'|trans
"string"|trans({}, "string2")
'string'|trans({}, 'string2')
'string'|trans({}, "string2")
"string"|trans({}, 'string2')
从相似性开始构建正则表达式。我们已经使用了两次以前使用过的相同字符串模式,可选的第二部分现在看起来像\\{\}、\.\\\\\\\\'.\'.\\\

这样我们就可以得到这样一个正则表达式:

const r = /^_[e_]\((\"(.*)\"|\'(.*)\')(, (\"(.*)\"|\'(.*)\'))?\);$/;

const xs = [
  "_e('string');",
  "_e(\"string\");",
  "_e('string', 'string2');",
  "_e(\"string\", 'string2');",
  "__('string');",
  "__(\"string\");",
  "__('string', 'string2');",
  "__(\"string\", 'string2');",
];

xs.forEach((x) => {
  const matches = x.match(r);

  if(matches){
    console.log('matches are:\n ', matches.filter(m => m !== undefined).join('\n  '));
  }else{
    console.log('no matches for', x);
  }
});
^(\"(.*)\"|\'(.*)\')\|trans\(\{\}, (\"(.*)\"|\'(.*)\')\))?$
请注意,这个正则表达式没有经过测试,只是我的猜测

经过进一步的讨论,很明显,我们在一个更大的文本堆中寻找几个匹配项。为了适应这种情况,我们需要从最里面的组中排除“和”字符,这就给我们留下了以下正则表达式:

_[e_]\(("([^"]*)"|\'([^']*)\')(, ("([^"]*)"|\'([^']*)\'))?\);
(\"(.*)\"|\'(.*)\')\|trans(\(\{\}, (\"(.*)\"|\'(.*)\')\))?

我还注意到,我的第二个正则表达式中显然有一个不匹配的括号。

我试图理解这些正则表达式的用途——以下是我的想法。让我省略两边的斜杠,以及属于该语言的字符串引号,而不是正则表达式本身

(__|_e)\(\"(.*)\"
(__|_e)\(\'(.*)\'
这样你就能得到上面8个正则表达式的所有命中率;但这可能不是你想要达到的

据我所知,您希望在代码中列出I18N引用,括号之间有一个或多个参数。我认为最好的方法是使用最简单的模式运行preg_match_:

(__|_e)\(.*\)
或者这个更好:

(__|_e)\([^\)]+\)     // works for multiple calls in one line, ignores empties
…然后逐个迭代结果并用逗号拆分:

foreach($matches as $m) {
    $args = explode(",",$m[1]);  // [1] = second subpattern
    ;
    ; // now you have the arguments of this function call
    ;
}

如果这个答案没有帮助,那么让我们进一步完善这个问题:

谢谢你,雅各布!我试过你的正则表达式,我想,我的问题让人困惑。所以我在regex tester中提供了这个例子。嘿,谢谢你的澄清。我已经用两个调整过的正则表达式更新了我的答案。我想,我已经回答了你的回答。我忘了。第一个正则表达式工作得很好!第二种方法还没有达到预期效果。我会设法弄清楚的。谢谢你,雅各布!你帮了大忙…谢谢你,德克尔纳!事实上,这不是我想要的。我只是举了一个例子。这可能比我的问题更容易理解D