Regex multiline mode not working as expected for optional group [duplicate]

喜你入骨 提交于 2019-12-12 01:46:03

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!