Reputation: 87719
I need to parse all those lines using a single regex (preg_match_all) command:
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
I should match (capturing groups) the file name and the line number
resources/assets/js/tests/example.spec.js
423
This is it (PHP) almost done: (?:\()([\/]*.*\/[^:]*):([0-9]+)
, but it's not matching all of them, here's it on regex101:
https://regex101.com/r/hM2sK8/15
Upvotes: 1
Views: 899
Reputation: 785128
You can use this regex:
~(/?(?:[\w.-]+/)*[\w.-]+):(\d+)~
RegEx Details:
(/?(?:[\w.-]+/)*[\w.-]+)
matches and groups file resource path:
match literal :
(\d+)
matches and groups number after :
Upvotes: 3
Reputation: 57388
If you also want to catch nonparenthesized filenames, you'd be better served by capturing "something resembling a full path followed by colon and a number":
<?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
));
returns:
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
This might come in handy ($gregs
is obtained as above):
$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);
Now $pairs
only contains one pair.
Upvotes: 3