如何使用正则表达式匹配文件名和行号?

时间:2017-10-09 16:47:55

标签: php regex preg-match

我需要使用单个正则表达式(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

enter image description here

2 个答案:

答案 0 :(得分:3)

如果你还想捕捉非虚拟化的文件名,你可以通过捕获“类似于完整路径然后冒号和数字的东西”来获得更好的服务:

<?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只包含一对。

答案 1 :(得分:3)

您可以使用此正则表达式:

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

Updated RegEx Demo

RegEx详细信息:

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