为了账号安全,请及时绑定邮箱和手机立即绑定

使用RegEx解析大字符串时出现java.lang.StackOverflowError

使用RegEx解析大字符串时出现java.lang.StackOverflowError

慕容708150 2019-12-03 15:56:38
这是我的正则表达式((?:(?:'[^']*')|[^;])*)[;]它在分号上标记字符串。例如,Hello world; I am having a problem; using regex;结果是三个字符串Hello worldI am having a problemusing regex但是当我使用较大的输入字符串时,会出现此错误Exception in thread "main" java.lang.StackOverflowErrorat java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)at java.util.regex.Pattern$Loop.match(Pattern.java:4295)at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)at java.util.regex.Pattern$BranchConn.match(Pattern.java:4078)at java.util.regex.Pattern$CharProperty.match(Pattern.java:3345)at java.util.regex.Pattern$Branch.match(Pattern.java:4114)at java.util.regex.Pattern$GroupHead.match(Pattern.java:4168)at java.util.regex.Pattern$Loop.match(Pattern.java:4295)at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)这是怎么引起的,我该如何解决?
查看完整描述

3 回答

?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

不幸的是,Java的内置正则表达式支持对包含重复性替代路径(即(A|B)*)的正则表达式存在问题。这被编译为递归调用,当在非常大的字符串上使用时,将导致StackOverflow错误。


一种可能的解决方案是重写正则表达式以不使用重复性替代方法,但是如果您的目标是在分号上标记字符串,那么您实际上根本不需要复杂的正则表达式,只需使用String.split()和简单";"的论据。


查看完整回答
反对 回复 2019-12-03
?
郎朗坤

TA贡献1921条经验 获得超9个赞

如果确实需要使用使堆栈溢出的正则表达式,则可以通过将-Xss40m之类的内容传递给JVM来增加堆栈的大小。


查看完整回答
反对 回复 2019-12-03
?
慕虎7371278

TA贡献1802条经验 获得超4个赞

在+之后添加a可能会有所帮助[^;],从而减少重复次数。


难道没有某种结构会说“如果正则表达式匹配到这一点,请不要回溯”?也许也派上用场。(更新:它被称为所有格修饰符)。


完全不同的选择是编写一个称为的实用程序方法splitQuoted(char quote, char separator, CharSequence s),该方法显式遍历字符串并记住它是否已看到奇数个引号。在该方法中,您还可以处理引号字符出现在带引号的字符串中时可能需要不转义的情况。


'I'm what I am', said the fox; and he disappeared.

'I\'m what I am', said the fox; and he disappeared.

'I''m what I am', said the fox; and he disappeared.


查看完整回答
反对 回复 2019-12-03
  • 3 回答
  • 0 关注
  • 998 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信