匹配传递函数/方法参数的正则表达式

时间:2016-02-07 18:55:55

标签: php regex preg-match

我已经仔细研究了之前提出这个问题的问题;唉,我搜索PHP preg_match搜索没有返回任何结果(也许我的搜索技能不足,我认为对齐认为这是一个正则表达式问题!)。

考虑以下文字:

  

快速__("brown ")狐狸跳__('over the')懒惰__("dog")

现在我需要'扫描'上面给定的方法__(''),而它可能包括间距和不同的引用(' | ")。经过无数次'迭代'之后我的最佳尝试:

(__\("(.*?)"\))|(__\('(.*?)'\))

或者以最简单的形式:

__\((.*?)\)

要解决这个问题:

  • __
  • 开头的任何内容
  • 转义(和引号"'。因此,\(\"
  • (.*?)所有角色的非贪婪匹配
  • 转步关闭"和最后一个括号。
  • 两个表达式之间的
  • |匹配/或。

但是,这只会获得部分匹配,并且空格会完全抛弃搜索。如果之前有人问过,请告诉我,如果有的话请联系我!

上面提供的模式的测试人员链接:

PHP Live Regex Test Tool

4 个答案:

答案 0 :(得分:2)

当搜索到的方法字符串使用单引号时,它将最终出现在另一个捕获组中,而不是具有双引号。所以实际上,你的正则表达式有效(除了空格,请参见下面的内容),但你必须在结果数组中查看不同的索引:

$input = 'The quick __("brown ") fox jumps __(\'over the\') lazy __("dog")';

// using your regular expression:
$res = preg_match_all("/(__\(\"(.*?)\"\))|(__\('(.*?)'\))/", $input, $matches);

print_r ($matches);

请注意,您需要preg_match_all而不是preg_match才能获得所有匹配。

输出:

Array
(
    [0] => Array
        (
            [0] => __("brown ")
            [1] => __('over the')
            [2] => __("dog")
        )
    [1] => Array
        (
            [0] => __("brown ")
            [1] => 
            [2] => __("dog")
        )
    [2] => Array
        (
            [0] => brown 
            [1] => 
            [2] => dog
        )
    [3] => Array
        (
            [0] => 
            [1] => __('over the')
            [2] => 
        )
    [4] => Array
        (
            [0] => 
            [1] => over the
            [2] => 
        )
)

因此,结果数组有5个元素,第一个表示完全匹配,所有其他元素对应于正则表达式中的4个捕获组。由于单引号的捕获组不是双引号的捕获组,因此您可以在不同的位置找到匹配项。

"解决" 这个,您可以在正则表达式中使用后向引用,这将回顾查看哪个是开头引号(单引号或双引号)并且需要同样要在最后重复:

$res = preg_match_all("/__\(([\"'])(.*?)\\1\)/", $input, $matches);

注意后面的引用\1(必须使用另一个反斜杠转义反斜杠)。这引用了第一个捕获组,我们有["'](再次需要转义)以匹配两种引号。

你也想要处理空间。在PHP Live Regex上,您使用了一个测试字符串,括号和引号之间有这样的空格。为了处理这些问题,他们仍然正确地匹配方法字符串,正则表达式应该另外增加两个\s*

$res = preg_match_all("/__\(\s*([\"'])(.*?)\\1\s*\)/", $input, $matches);

现在输出是:

Array
(
    [0] => Array
        (
            [0] => __("brown ")
            [1] => __('over the')
            [2] => __("dog")
        )
    [1] => Array
        (
            [0] => "
            [1] => '
            [2] => "
        )
    [2] => Array
        (
            [0] => brown 
            [1] => over the
            [2] => dog
        )
)

...现在很好地安排了小组拍摄的文字。

请在eval.inPHP Live Regex上查看此代码。

答案 1 :(得分:1)

当处理这样的事情时,不要忘记逃避:

<?php
ob_start();
?>

The quick __("brown ") fox jumps __(  'over the'  ) lazy __("dog").
And __("everyone says \"hi\"").

<?php

$content = ob_get_clean();

$re = <<<RE
    /__ \(
        \s*
        " ( (?: \\\\. | [^"])+ ) "
        |
        ' ( (?: \\\\. | [^'])+ ) '
        \s*
    \)
    /x
RE;

preg_match_all($re, $content, $matches, PREG_SET_ORDER);
foreach($matches as $match)
    echo end($match), "\n";

答案 2 :(得分:0)

这个怎么样:

 (__(\('[^']+'\)|\("[^"]+"\)))

使用除引号.[^']

之外的任何字符,而不是非贪婪的[^"]

答案 3 :(得分:0)

用方括号括起双引号和单引号作为字符类:

$str = 'The quick __( "brown ") fox jumps __(\'over the\') lazy __("dog")';

preg_match_all("/__\(\s*([\"']).*?\\1\s*\)/ium", $str, $matches);

echo '<pre>';
var_dump($matches[0]);

// the output:
array (size=3)
    0 => string '__( "brown ")' 
    1 => string '__('over the')'
    2 => string '__("dog")'

以下是 phpliveregex.com 上相同解决方案的示例:
 http://www.phpliveregex.com/p/exFpreg_match_all部分)