java正则表达式中的堆栈溢出
Posted
技术标签:
【中文标题】java正则表达式中的堆栈溢出【英文标题】:Stack Overflow in java regex 【发布时间】:2013-08-09 23:45:48 【问题描述】:我是java新手。我在正则表达式 strHindiText 中收到 java Stack overflow 异常。 我该怎么做?
try
// This regex convert the pattern "\fldrslt \fcs1 \ab\af24 \fcs0 ऩ"
// into "\fldrslt \fcs1 \ab\af24 \fcs0 ऩ"
// strHindiText = strHindiText.replaceAll("\\(\\\\fldrslt[ ])\\((\\\\\\S+[ ])+)((\\s*&#\\d+;\\s*(-|,|/|\\(|\\)|\"|;|\\.|'|<|>|:|\\?)*)+)\\\\","$1$2$4");
// This regex convert the pattern "\fcs0 \af0 ऩ or \fcs0 \af0 *\tab ऩ"
// into "\fcs0 \af0 ऩ "
strHindiText = strHindiText.replaceAll("\\\\s*((\\\\\\S+[ ](\\*)?)+\\s*)(-|,|/|\\(|\\)|\"|;|\\.|'|<|>|:|\\?)*[ ]*(((&#\\d+;)[ ]*(-|,|/|\\(|\\)|\"|;|\\.|'|<|>|:|\\?)*[ ]*)+)\\", "$1 $4$5 ");
// This regex convert the pattern "ऩ \fcs0 \af0 "
// into "ऩ \fcs0 \af0 "
strHindiText = strHindiText.replaceAll("\\\\s*(((&#\\d+;)[ ]*(-|,|/|\\(|\\)|\"|;|\\.|'|<|>|:|\\?)*[ ]*)+)[ ]*((\\\\\\S+[ ])+)\\", "$1 $5 ");
catch(***Error er)
System.out.println("Third try Block ***Error in regex pattern to reform the rtf tags................");
er.printStackTrace();
// throw er;
每当这些 strHindiText 包含大数据时,它都会给出 java *** 异常:
java.lang.***Error
2013-08-08 15:35:07,743 ERROR [STDERR] (http-127.0.0.1-80-9) at java.util.regex.Pattern$Curly.match0(Pattern.java:3754)
2013-08-08 15:35:07,743 ERROR [STDERR] (http-127.0.0.1-80-9) at java.util.regex.Pattern$Curly.match(Pattern.java:3744)
2013-08-08 15:35:07,744 ERROR [STDERR] (http-127.0.0.1-80-9) at java.util.regex.Pattern$GroupTail.match(Pattern.java:4227)
2013-08-08 15:35:07,744 ERROR [STDERR] (http-127.0.0.1-80-9) at java.util.regex.Pattern$BmpCharProperty.match(Pattern.java:3366)
2013-08-08 15:35:07,745 ERROR [STDERR] (http-127.0.0.1-80-9) at java.util.regex.Pattern$Curly.match0(Pattern.java:3782)
2013-08-08 15:35:07,745 ERROR [STDERR] (http-127.0.0.1-80-9) at java.util.regex.Pattern$Curly.match(Pattern.java:3744)
我的 strHindiText 数据是:
`\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf21\insrsid13505584 भोपाल  । \par \pard\plain \ltrpar\s16\ql \li0\ri0\sb100\sa100\sbauto1\saauto1\sl240\slmult0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\pararsid13505584 \cbpat20 \rtlch\fcs1 \af0\afs24\alang1025 \ltrch\fcs0 \fs24\lang1033\langfe1033\cgrid\langnp1033\langfenp1033 \rtlch\fcs1 \ab\af1\afs18 \ltrch\fcs0 \cs21\b\f1\fs18\cf21\insrsid13505584 अन्वेषण करें  :\rtlch\fcs1 \af1\afs18 \ltrch\fcs0 \f1\fs18\cf21\insrsid13505584 \par भोपाल , मध्य प्रदेश की राजधानी प्राकृतिक सुंद`
【问题讨论】:
您的替代路径|
可能会导致递归调用,从而导致堆栈溢出。正则表达式的东西通常很复杂,而且你的正则表达式很大。我并不感到惊讶。
我建议不要使用替代符号(例如a|b|c
)来使用替代符号:[abc]
,这应该使正则表达式更清晰,您只需要转义右括号而不是其他字符.此外,您似乎想要做一些正则表达式不适合的事情 - 解析 - 对于不是文本但具有更高顺序的东西。
你真的不应该使用 RegEx
进行如此庞大的解析。它的性能不是很好,因为每次你尝试匹配一个字符串时,正则表达式都会编译。
您的代码的一切都是询问的问题。尝试将问题分解为多个小问题,而不是尝试使用巨大的正则表达式一次完成大量事情。根据您使用的正则表达式,如果您没有遇到内存问题,我会感到惊讶。
我个人建议为您的 RTF 编写解析器,而不是尝试使用正则表达式对其进行拆分。正则表达式适用于简单的事情,我认为印地语中的 RTF 一点也不简单。
【参考方案1】:
这不是一个完整的答案,仅供您参考。
在你的正则表达式中:
(-|,|/|\\(|\\)|\"|;|\\.|'|<|>|:|\\?)*
可以写成[-,/()\";.'<>:?]*
由于这种模式出现了两次(在您的第一个正则表达式中),这会立即将您的正则表达式缩短 40 个字符,并使这些部分更具可读性。
【讨论】:
【参考方案2】:选项 1 - 治疗症状
在您的正则表达式中查找递归调用。
如果您不确定问题出在哪里:请尝试a regex tester like this。
选项 2 - 治疗原因(更好)
如果有更好的工具来完成您的任务,请不要使用正则表达式。
在您的情况下,您可以:搜索 RTF 解析库或编写自己的解析器。 例如就像 jahroy 在 cmets 中指出的 here。
【讨论】:
【参考方案3】:试试这个来捕捉错误
public class Example
public static void endless()
endless();
public static void main(String args[])
try
endless();
catch(***Error t)
// more general: catch(Error t)
// anything: catch(Throwable t)
System.out.println("Caught "+t);
t.printStackTrace();
System.out.println("After the error...");
更重要的是尝试增加堆栈的大小,将其添加到您的正则表达式中
+'xss='xss
添加“+”符号会更改运算符以防止回溯,因为在您的情况下这似乎不是必需的。
【讨论】:
他应该考虑使用正确的工具来完成工作,而不是治疗使用错误工具所导致的症状...... 可能溢出来自递归问题而不是正则表达式的贪婪。通过使运算符具有所有格性,我们可以消除分支和递归处理,从而使该表达式更高效并减少内存使用。 我要么找一个 RTF 解析库,要么自己写一个。如果我自己写一个,我会将解析分解为小任务,而不是尝试一次完成所有事情。如果我不得不使用正则表达式,我会让它们保持小而简单,并确保它们只对小段文本进行操作。我永远不会考虑将整个文档提供给单个复杂的正则表达式。 谷歌搜索大约需要 5 秒才能找到 this(也许会有所帮助,也许不会……) 好的。对不起,如果我的 cmets 过于苛刻。整个“我必须使用正则表达式”的心态在这个网站上是如此普遍,以至于有时让你想从山顶尖叫:“并非所有问题都必须用正则表达式解决!"以上是关于java正则表达式中的堆栈溢出的主要内容,如果未能解决你的问题,请参考以下文章
将 po box javascript 正则表达式转换为 c# 正则表达式