簡體   English   中英

Java Matcher and Pattern:為什么這會永遠持續下去

[英]Java Matcher and Pattern: Why does this go on forever

//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 我不知道為什么 嘗試重置,但一無所獲。

我不知道您要完成什么,但是這里有一個錯誤:

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

您正在重新分配str ,而匹配器仍按str的原始值工作。 字符串是不可變的,如果在一個位置重新分配變量,則不會在另一個位置更改引用(請參見Sun Java Tutorial本頁上的 傳遞引用數據類型參數 )。

還有更多奇怪的事情發生,但也許我對您的理解不正確。 您在注釋中說,字符串以ACCEPT開頭,以結束。 但這是您正在搜索Pattern.compile("ACCEPT .*?\\\\.",Pattern.DOTALL);的唯一內容Pattern.compile("ACCEPT .*?\\\\.",Pattern.DOTALL); ,您也不會捕獲任何東西。 那為什么要首先打擾呢? 我以為您知道輸入字符串就是這樣。

您真正應該做的是發布一些樣本輸入以及您想要從中提取什么數據。 否則,沒人會真正幫助您。


我現在正在猜測:您似乎想從String中刪除多個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

給定您更新的要求(刪除WITH,但保留args),這是一個更新的解決方案:

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());

輸出:

接受意大利面配番茄,帕瑪森芝士,橄欖an魚和更多金槍魚橄欖。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM