Причина сбоя механизма регулярных выражений Java заключается в том, что эта часть регулярного выражения вызывает переполнение стека (действительно!):
[\s]|[^<]
Что здесь происходит, так это то, что каждому символу, сопоставленному с \ s, также может соответствовать [^ <]. Это означает, что есть два способа сопоставить каждый символ пробела. Если мы представляем два класса символов с A и B: </p>
A|B
Тогда строка из трех пробелов может быть сопоставлена как AAA, AAB, ABA, ABB, BAA, BAB, BBA или BBB. Другими словами, сложность этой части регулярного выражения равна 2 ^ N. Это убьет любой движок регулярных выражений, который не имеет никаких гарантий против того, что я называю катастрофическим возвратом .
При использовании чередования (вертикальная черта) в регулярном выражении всегда следите за тем, чтобы альтернативы были взаимоисключающими. То есть не более одной из альтернатив может быть разрешено совпадать с любым данным битом текста.