douluoxiao2286 2016-02-07 18:55
浏览 100
已采纳

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

I've had a good look around for a question that asked this before; alas, my search for a PHP preg_match search returned no results (maybe my searching skills fell short, I suppose justified considering it's a Regex question!).

Consider the text below:

The quick __("brown ") fox jumps __('over the') lazy __("dog")

Now currently I need to 'scan' for the given method __('') above, whereas it could include the spacing and different quotations ('|"). My best attempt after numerous 'iterations':

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

Or at its simplest form:

__\((.*?)\)

To break this down:

  • Anything that starts with __
  • Escaped ( and quotation mark " or '. Thus, \(\"
  • (.*?) Non-greedy match of all characters
  • Escaped closing " and last bracket.
  • | between the two expressions match either/or.

However, this only gets partial matches, and spaces are throwing off the search entirely. Apologies if this has been asked before, please link me if so!

Tester Link for the pattern provided above:

PHP Live Regex Test Tool

  • 写回答

4条回答 默认 最新

  • dongpao1921 2016-02-07 19:48
    关注

    When the searched method string uses single quotes it will end up in another capture group than if it has double quotes. So in fact, your regular expression works (except for the spaces, see further down), but you'd have to look at a different index in your result array:

    $input = 'The quick __("brown ") fox jumps __(\'over the\') lazy __("dog")';
    
    // using your regular expression:
    $res = preg_match_all("/(__\(\"(.*?)\"\))|(__\('(.*?)'\))/", $input, $matches);
    
    print_r ($matches);
    

    Note that you need preg_match_all instead of preg_match to get all matches.

    Output:

    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] => 
            )
    )
    

    So, the result array has 5 elements, the first one representing the complete match, and all the others correspond to the 4 capture groups you have in your regular expression. As the capture groups for single quotes are not those of the double quotes, you'll find the matches at different places.

    To "solve" this, you could use a back reference in your regular expression, which would look back to see which was the opening quote (single or double) and require the same to be repeated at the end:

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

    Note the back reference \1 (the backslash had to be escaped with another one). This refers back to the first capture group, where we have ["'] (again an escape was necessary) to match both kinds of quotes.

    You also wanted to deal with spaces. On your PHP Live Regex you used a test string that had such spaces between the brackets and quotes. To deal with these so they still match the method strings correctly, the regular expression should get two additional \s*:

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

    Now the output is:

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

    ... and the text captured by the groups is now nicely arranged.

    See this code run on eval.in and PHP Live Regex.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(3条)

报告相同问题?

悬赏问题

  • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?
  • ¥15 有偿四位数,节约算法和扫描算法
  • ¥15 VUE项目怎么运行,系统打不开
  • ¥50 pointpillars等目标检测算法怎么融合注意力机制
  • ¥20 Vs code Mac系统 PHP Debug调试环境配置
  • ¥60 大一项目课,微信小程序
  • ¥15 求视频摘要youtube和ovp数据集