【问题标题】:How to use regex to match file name and line number?如何使用正则表达式匹配文件名和行号?
【发布时间】:2017-10-09 16:47:55
【问题描述】:

我需要使用单个正则表达式 (preg_match_all) 命令解析所有这些行:

at Object..test (resources/assets/js/tests/example.spec.js:423:23)
(/resources/assets/js/tests/example.spec.js:423)
/resources/assets/js/tests/example.spec.js:423
resources/assets/js/tests/example.spec.js:423

我应该匹配(捕获组)文件名和行号

resources/assets/js/tests/example.spec.js
423

这就是它(PHP)几乎完成了:(?:\()([\/]*.*\/[^:]*):([0-9]+),但它并不匹配所有这些,这是 regex101 上的:

https://regex101.com/r/hM2sK8/15

【问题讨论】:

  • 你为什么要匹配(?删除(?:\()) 不行吗?
  • (?:\() 有效,但它不匹配不以( 开头的任何内容
  • 你不是得到你想要的文件名和行号,还是你想匹配最后两行? regex101.com/r/hM2sK8/16
  • 但是你的演示已经开始工作了不是吗?
  • 是的,它应该匹配所有行。

标签: php regex preg-match


【解决方案1】:

如果您还想捕获未带括号的文件名,最好捕获“类似于完整路径后跟冒号和数字的东西”:

<?php
    $test = <<<TEST
at Object..test (resources/assets/js/tests/example.spec.js:423:23)
(/resources/assets/js/tests/example.spec.js:423)
/resources/assets/js/tests/example.spec.js:423
resources/assets/js/tests/example.spec.js:423
TEST;
    preg_match_all('#([A-Za-z0-9/\._-]+):([1-9][0-9]*)#', $test, $gregs, PREG_SET_ORDER);

   print implode(array_map(
       function ($set) {
            return "Found {$set[1]} at line {$set[2]}\n";
       },
       $gregs
    ));

返回:

Found resources/assets/js/tests/example.spec.js at line 423
Found /resources/assets/js/tests/example.spec.js at line 423
Found /resources/assets/js/tests/example.spec.js at line 423
Found resources/assets/js/tests/example.spec.js at line 423

获取唯一的文件/行对

这可能会派上用场($gregs如上获得):

    $pairs = array_map(
       function ($set) {
           if (0 !== strpos($set[1], '/')) {
               return [ "/{$set[1]}", $set[2] ];
           }
           return [ $set[1], $set[2] ];
       },
       $gregs
    );

    $pairs = array_map(
        'unserialize',
        array_unique(
            array_map(
                'serialize',
                $pairs
            )
        )
    );

    print_r($pairs);

现在$pairs 只包含一对。

【讨论】:

  • 您没有使用.^$,因此不需要修饰符。也可以用元字符 ([\w/.-]+):([1-9]\d*) 缩短正则表达式 a。
  • @chris85 ,很好的修饰符。您对元字符也是正确的,但我通常更喜欢将它们保留为纯文本。解析器无论如何都会扩展它们,我觉得我更能够以这种方式可视化字符串。当然,这些只是我的口味!
  • @AntonioCarlosRibeiro,请注意 - 看到我使用了 - 或 _ 之类的字符,很明显。在文件名中。您可能需要添加其他字符,具体取决于您的文件命名方案,例如“ClassOne,Debug.js”有一个逗号(我曾经见过这样的方案),并且可能有空格或 @'s。
【解决方案2】:

你可以使用这个正则表达式:

~(/?(?:[\w.-]+/)*[\w.-]+):(\d+)~

Updated RegEx Demo

正则表达式详细信息:

  • (/?(?:[\w.-]+/)*[\w.-]+) 匹配和分组文件资源路径
  • : 匹配文字 :
  • (\d+): 之后匹配和分组编号

【讨论】:

  • (/resources/assets/js/tests/example.php:449)上的第一个/不匹配
  • 哦,这很容易处理......请参阅更新的正则表达式。
  • 顺便说一句,接受答案的正则表达式也将匹配 ////:35 作为有效匹配项。
猜你喜欢
  • 1970-01-01
  • 2020-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多