2010-12-02 55 views
0
//remove multiple with 
     pat=Pattern.compile("ACCEPT .*?\\.",Pattern.DOTALL); 
     m=pat.matcher(str);  
     while(m.find()) 
     { 

      int start=m.group().indexOf("WITH") +1; 
      String part=m.group().substring(start); 
      part=part.replaceAll("WITH", ""); 
      part=m.group().substring(0, start).concat(part); 

      if(!m.group().equals(part)) 
      { 

       str=m.replaceFirst(part); 

      } 

     } 

任何想法为什么这是一个无限循环? m.group永远不会等于part。我不知道为什么。尝试重置,但没有。Java匹配和模式:为什么这会一直持续下去

+1

什么是您的输入字符串? – 2010-12-02 12:46:45

+0

它变化..它开始于接受和结束。点.. – GorillaApe 2010-12-02 12:47:43

回答

4

我不知道你所要完成的,但这里有一个错误:

if(!m.group().equals(part)) 
{ 
    str=m.replaceFirst(part); 
} 

您重新分配str,而匹配仍然有效上str原始值。字符串是不可变的,如果您在一个地方重新分配变量,它不会在另一个地方更改引用(请参阅传递参考数据类型参数 on this page of the Sun java Tutorial)。

还有一些更奇怪的事情正在进行,但也许我没有正确理解你。 你在评论中说,字符串开始于接受和结束。点。但这是你正在寻找的唯一东西Pattern.compile("ACCEPT .*?\\.",Pattern.DOTALL);,而且你也没有捕获任何东西。那么为什么要打扰搜索呢?我以为你知道输入字符串就是这样。

你真正应该做的是发布一些示例输入和你想从中提取的数据。否则,没有人能够真正帮助你。


我现在猜测:你似乎想要从你的字符串中删除多个WITH子句。这应该是容易得多,这样的事情:

String test = 
    "ACCEPT pasta " 
     + "WITH tomatoes, parmesan cheese, olives " 
     + "WITH anchovies WITH tuna WITH more olives."; 

System.out.println(
    test.replaceAll(
     "(ACCEPT.*?WITH.*?)(?:\\s*WITH.*)(\\.)", "$1$2" 
    ) 
); 

输出:

接受番茄,帕玛森干酪 ,橄榄面食。

这里的模式,解释说:

(  // start a capturing group 
ACCEPT // search for the literal ACCEPT 
.*?  // search for the shortest possible matching String 
     // (so no other WITH can sneak in) 
WITH // search for the literal WITH 
.*?  // search for the shortest possible matching String 
     // (so no other WITH can sneak in) 
)  // close the capturing group, we'll refer to this 
     // group as $1 or matcher.group(1) 
(?:  // start a non-capturing group 
\\s* // search for optional whitespace 
WITH // search for the literal WITH 
.*  // search for anything, greedily 
)  // close the group, we'll discard this one 
(  // open another capturing group 
\\.  // search for a single period 
)  // close the group, the period is now accessible as $2 

鉴于你的更新要求(除去WITHs但保留参数)这里是一个更新的解决方案:

final Matcher matcher = 
    Pattern.compile("WITH\\s*", Pattern.DOTALL).matcher(test); 
final StringBuffer sb = new StringBuffer(); 
while(matcher.find()){ 
    matcher.appendReplacement(sb, sb.length() == 0 
     ? matcher.group() 
     : ""); 
} 
matcher.appendTail(sb); 
System.out.println(sb.toString()); 

输出:

接受西红柿,干酪,橄榄凤尾鱼金枪鱼通心粉更多橄榄。