Java正则表达式匹配开始/结束标签导致堆栈溢出

JavaPattern该类的标准实现使用递归来实现多种形式的正则表达式(例如,某些运算符,替换)。

这种方法会导致输入字符串超过(相对较小)长度(可能不超过1,000个字符)的堆栈溢出问题,具体取决于所涉及的正则表达式。

一个典型的例子是以下正则表达式,它使用交替Data从周围的XML字符串中提取可能的多行元素(名为),该元素已经提供了:

<Data>(?<data>(?:.|\r|\n)+?)</Data>

上面的正则表达式与该Matcher.find()方法一起使用,以读取“数据”捕获组并按预期工作,直到提供的输入字符串的长度超过1200个字符左右,在这种情况下,这会导致堆栈溢出。

可以重写上面的正则表达式以避免堆栈溢出问题吗?

回答:

有关堆栈溢出问题起源的更多详细信息:

有时regex

Pattern类会抛出StackOverflowError。这是已知错误#5050507的体现,该错误java.util.regex自Java 1.4

起已包含在软件包中。该错误将保留,因为它具有“无法修复”状态。发生此错误的原因是Pattern该类将正则表达式编译为一个小程序,然后执行该小程序以查找匹配项。该程序以递归方式使用,并且有时在进行过多的递归调用时会发生此错误。有关更多详细信息,请参见错误说明。

您的正则表达式(具有交替项)与两个标签之间的任意1个以上的字符匹配。

您可以使用带有Pattern.DOTALL修饰符(或等效的嵌入式标志(?s))的惰性点匹配模式,该修饰符也会使.匹配换行符:

(?s)<Data>(?<data>.+?)</Data>

观看此正则表达式演示

但是,在输入量巨大的情况下,惰性点匹配模式仍会消耗大量内存。最好的解决方法是使用

展开循环方法

<Data>(?<data>[^<]*(?:<(?!/?Data>)[^<]*)*)</Data>

参见正则表达式演示

  • <Data> -文字 <Data>
  • (?<data> -捕获组“数据”的开始

    • [^<]* -零个或多个其他字符 <
    • (?:<(?!/?Data>)[^<]*)* -0个或多个序列:
    • <(?!/?Data>)- <后面没有Data>或的/Data>
    • [^<]* -零个或多个其他字符 <

  • ) -“数据”组的结尾
  • </Data> -结束定界符

以上是 Java正则表达式匹配开始/结束标签导致堆栈溢出 的全部内容, 来源链接: utcz.com/qa/401375.html

回到顶部