Проблема здесь:
"(?:" + // One or more:
"[^\\s()<>]+" + // Run of non-space, non-()<>
"|" + // or
"\\((?:[^\\s()<>]+|(?:\\([^\\s()<>]+\\)))*\\)" + // balanced parens, up to 2 levels
")+"
Здесь у вас есть вложенные квантификаторы . Это приводит к хаосу с любым алгоритмом обратного отслеживания - в качестве примера рассмотрим регулярное выражение /^(a+)+$/
, совпадающее со строкой
aaaaaaaaaab
В качестве первой попытки внутренний квантификатор будет соответствовать всем a
с. Тогда регулярное выражение терпит неудачу, поэтому оно отступает от одного. Затем внешний квантификатор снова пытается найти соответствие, сглотнув последний a
, затем регулярное выражение снова выходит из строя. Мы в основном получаем экспоненциальное поведение, так как квантификаторы пробуют всевозможные способы разделить серию a
с, фактически не добиваясь прогресса.
Решением является притяжательные квантификаторы (которые мы обозначаем прикреплением +
к концу квантификатора) - мы устанавливаем внутренние квантификаторы таким образом, чтобы после того, как у них есть совпадение, они не отпусти - они будут держаться до тех пор, пока совпадение не завершится или более ранний квантификатор не отступит, и им придется пересчитать, начиная где-то еще в строке. Если бы вместо этого мы использовали /^(a++)+$/
в качестве нашего регулярного выражения, мы немедленно потерпели бы неудачу в приведенной выше несоответствующей строке, а не стали экспоненциально пытаться сопоставить ее.
Попробуйте сделать эти внутренние квантификаторы притяжательными и посмотрите, поможет ли это.