问题
I have a next text source:
PHPUnit 5.7.5 by Sebastian Bergmann and contributors. .....................E.....R................................. 61 / 1485 ( 1%) ..................... 1485 / 1485 (100%) Time: 1.51 minutes, Memory: 102.00MB ---error details skipped--- ERRORS! Tests: 1485, Assertions: 14821, Errors: 1, Failures: 1.
I need to parse in real time (streamed output to stdout) next symbols: EFWIRS.
(error, failure, warning, etc) and if available statistics line (numbers and percent in EOL). So, in results I except something like that:
.......
or
.....................E.....R.................................
or
.....................E.....R................................. 61 / 1485 ( 1%)
or
..................... 1485 / 1485 (100%)
but not
.....................E.....R................................. 61 / 1485 (
or
.....................E.....R................................. 61 / 1485 ( 1
or
.....................E.....R................................. 61 /
My regex is /^[EFWIRS.]+\s*(?:\d+\s\/\s\d+\s\(\s*\d+%\)\n)?/m
but it also match extra ERR
string in case if tests failed (look at output example). I try /^[EFWIRS.]+\s*(?:\d+\s\/\s\d+\s\(\s*\d+%\))?$/m
, but this regex is skip lines with incompleted statistics block completely and match only whole string despite the optional group (...)?
, that works in first regex as expected.
P.S. I know about custom printers for PHPUnit, but in my case they are not suitable and I need to parse common output.
回答1:
I believe you have to use lookahead to ensure both correct characters to match and correct consequence of them in a line.
I've made an example for you here. The pattern itself is ^([EFWIRS.](?=[EFWIRS.\s]))+\s+(\d+\s*\/\s*\d+\s*\(\s*\d+%\s*\))?$
I am not sure about your mechanism of output capturing so can't advise on modifiers and which PHP regex functions to use. Example down by the link assumes full multiline text so it uses global and multiline modifiers (meaning preg_match_all
and #pattern#m
would be used in php code).
回答2:
This simple regex works in all provided examples if you don't need the statistics part.
[.EFWIRS]+(?=\s+\d)
.
Link to the regex
Negative lookahead suites better in this case than non-capturing group.
来源:https://stackoverflow.com/questions/41808736/regex-multiline-mode-not-working-as-expected-for-optional-group