Если регулярное выражение в форме (x|ab)*
вызывает переполнение стека или другие сбои в вашем механизме регулярных выражений (как упомянуто в ссылке madbean.com в исходном вопросе), вот несколько советовпереписать такое регулярное выражение.
Регулярное выражение (x|ab)*
состоит из группы захвата с двумя альтернативами, которые являются взаимоисключающими.Это регулярное выражение может быть оптимизировано тремя способами, в зависимости от функций, поддерживаемых вашим регулярным выражением.Аромат java.util.regex поддерживает все 3.
Группа захвата будет сохранять текст, найденный во время последней итерации после успешного совпадения, или x
или ab
.Поскольку вам, вероятно, наплевать на последнюю итерацию, вы можете сказать движку регулярных выражений, что вам все равно, и использовать группу без захвата: (?:x|ab)*
.Степень увеличения скорости зависит от того, как механизм регулярных выражений отслеживает группы захвата.
Альтернативы являются взаимоисключающими.Если x
совпадает, нет смысла пытаться сопоставить ab
в той же позиции.Вы можете указать обработчику регулярных выражений, что с помощью атомарной группы: (?>x|ab)*
Атомные группы не захватываются, поэтому это сохраняет предыдущую оптимизацию.
За вашей повторной группой (?>x|ab)*
не следует ничего, что могло бы соответствоватьтот же текст, что и x
или ab
.Таким образом, квантификатор *
может соответствовать как можно большему числу итераций, без необходимости возвращать, чтобы остальная часть регулярного выражения соответствовала.Вы можете указать обработчику регулярных выражений, что с помощью собственнического квантификатора: (?>x|ab)*+
В зависимости от того, как движок java.util.regex обрабатывает возврат и подавление его с помощью атомарных групп и притяжательных квантификаторов, любой из этих оптимизаций илиих комбинация вполне может избежать переполнения стека.Даже если этого не произойдет, и вы решите использовать другой механизм регулярных выражений, эти методы все равно могут повысить производительность ваших регулярных выражений.