透过正则表达式替换字符串报 java.lang.StackOverflowError

通过正则表达式替换字符串报 java.lang.StackOverflowError大家可以运行下面这段测试代码看看,是不是会抛

通过正则表达式替换字符串报 java.lang.StackOverflowError
大家可以运行下面这段测试代码看看,是不是会抛出java.lang.StackOverflowError异常,如果把str长度缩减一些倒是可以正常运行,如果在你的上没有抛出异常,请再增加str的长度试试

测试代码:
====================================

import   java.util.regex.Matcher;
import   java.util.regex.Pattern;

public   class   ProgramTest   {
public   static   void   main(String[]   args)   throws   Exception   {
String   str   =   "[quote=username]\r\n测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试n[/quote]bbbbbbbb ";
String   re   =   "\\[quote=(.[^\\[]*)\\]((.|\\s)*)\\[\\/quote\\] ";
Pattern   pattern   =   Pattern.compile(re);
Matcher   matcher   =   pattern.matcher(str);

System.out.println(matcher.replaceAll(   " "   ));
}
}


[解决办法]
一样的,string太长了。
[解决办法]
str.indexOf( "quote ")
substring

细节可以自己考虑~~
[解决办法]
既然有长度限制,就饶开嘛:

import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Test {
public static void main(String[] args) throws Exception {
int maxLen = 820;
String str = "[quote=username]\r\nn[/quote]bbbbbbbb ";
String re = "\\[quote=(.[^\\[]*)\\]((.|\\s)*)\\[\\/quote\\] ";
Pattern pattern = Pattern.compile(re);
int length = str.length() / maxLen;
String subStr = " ";
for (int i = 0; i <= length; i++) {
subStr = str.substring(i * maxLen, ((i+1)*maxLen > str.length())?str.length():(i+1)*maxLen);
Matcher matcher = pattern.matcher(subStr);
System.out.println(matcher.replaceAll( " "));
}
}
}
[解决办法]
public static void main(String[] args) {
  String str = "[quote=username]a\r\n....n[/quote] bbbbbbbb ";    
  int start = -1;
  int end = -1;
  Pattern pattern = Pattern.compile( "\\[quote=(.[^\\[]*)\\] ");
  Matcher matcher = pattern.matcher(str);
  if(matcher.find()) {
    start = matcher.end();
  }
  end = str.lastIndexOf( "[/quote] ");
  if(start > -1 && end > -1) {
    str = str.replace(str.substring(start, end), " ");
  }
  System.out.println(str);
}
[解决办法]
如果标记也不需要的话稍微改成:

if(matcher.find()) {
  start = matcher.start();
}
end = str.lastIndexOf( "[/quote] ") + "/[quote] ".length();


[解决办法]
这是JDK的Bug,呵呵,超过长度限制了的就会抛这种异常
[解决办法]
不采用正则表达式(正则表达式的效率比较低),直接使用字符串进行处理。

int start = -1;
int end = -1;
start = str.indexOf( "[quote= ");
end = str.lastIndexOf( "[/quote] ") + "/[quote] ".length();
if(start > -1 && end > -1 && end > start) {
  str = str.substring(0, start) + str.substring(end);
}
System.out.println(str);

这不是 JDK 的 Bug,正则表达式的实现是通过栈来进行了,也就是将字符一个一个地压入栈中,由于其中的字符太多,导致栈不够用了,所以就产生溢出了。
[解决办法]
public static void ttt(){
String str = "[quote=username]\r\n测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试\n[/quote] bbbbbbbb ";
String re = "\\[quote=.*?\\](.*?)\\[\\/quote\\] ";
Pattern pattern = Pattern.compile(re,Pattern.DOTALL + Pattern.MULTILINE);
Matcher matcher = pattern.matcher(str);
String qt = " ";
if (matcher.find()){
qt = matcher.group(1);
System.out.println(qt);
System.out.println(str.replace(qt, " "));
}
}

结果:

测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试测试

[quote=username][/quote] bbbbbbbb

----------------------

不是string太长了,是你的模式没写对~
我写过的string要比这个长多了,
用这个匹配都没问题的~

[解决办法]
产生这个异常的主要原因是 Pattern 中的 matcher 采用了递归调用,字符较多产生了栈溢出。
[解决办法]
bao110908(长牙了,好痛):哦?请问这个栈的长度是由什么来决定的?
[解决办法]
String re = "\\[quote=.*?\\](.*?)\\[\\/quote\\] ";
Pattern pattern = Pattern.compile(re,Pattern.DOTALL + Pattern.MULTILINE);

看看上面我的代码~
------解决方案--------------------


to: sureyor

Java 中不是有栈空间和堆空间吗?具体的大小是由 Java 虚拟机来分配的,具体的大小我也不大清楚。