2013-01-10 40 views
1

我試圖用長字符串替換某些單詞。會發生什麼是一些話保持不變,有些改變。不改變的詞似乎讓matcher卡住了一個無限循環,因爲它不斷嘗試對保持不變的單詞執行相同的操作。下面是一個類似於我的例子 - 我不能把我使用的確切代碼,因爲它更詳細,會佔用太多的空間,我害怕。匹配查找無限循環

public String test() { 
    String temp = "<p><img src=\"logo.jpg\"/></p>\n<p>CANT TOUCH THIS!</p>"; 
    Pattern pattern = Pattern.compile("(<p(\\s.+)?>(.+)?</p>)"); 
    Matcher matcher = pattern.matcher(temp); 
    StringBuilder stringBuilder = new StringBuilder(temp); 
    int start; 
    int end; 
    String match; 

    while (matcher.find()) { 
     start = matcher.start(); 
     end = matcher.end(); 
     match = temp.substring(start, end); 
     stringBuilder.replace(start, end, changeWords(match)); 
     temp = stringBuilder.toString(); 
     matcher = pattern.matcher(temp); 
     System.out.println("This is the word I'm getting stuck on: " + match); 
    } 
    return temp; 
} 

public String changeWords(String words) { 
    return "<p><img src=\"logo.jpg\"/></p>"; 
} 

任何有關爲什麼會發生這種情況的建議?

回答

0

你正在尋找匹配的「文本」字樣,並再次更換這個詞或者與「文本」(如果條件changeWord())或「新文本」(否則在changeWord())。這可能會導致無限循環。

+0

我知道。我上面放置的例子有意用來說明這樣一個事實:有些單詞可能保持不變,但匹配器應該移到下一個匹配上,而不是在同一個匹配上空轉。 – ThreaT

1

您正在使用Matcher錯誤。 while循環讀取:

while (matcher.find()) { 
    start = matcher.start(); 
    end = matcher.end(); 
    match = temp.substring(start, end); 
    stringBuilder.replace(start, end, changeWords(match)); 
    temp = stringBuilder.toString(); 
    matcher = pattern.matcher(temp); 
} 

它應該僅僅是:

matcher.replaceAll(temp, "new text"); 

不 「而」 循環,這是不必要的。一個匹配不會替換文本不匹配,它會做正確的工作與問候到在同一個地方等不匹配兩次 - 無需spoonfeed它。

更重要的是,你的正則表達式可以不用捕獲括號。如果你只是想取代「字」(正則表達式無以言表的概念),加字錨文本週圍要匹配:

Pattern pattern = Pattern.compile("\\btext\\b"); 
+0

問題是我需要'start'和'end'變量。它們包含在代碼的其他區域傳遞的索引。如果我使用'replaceAll',那麼我就無法再訪問這些參數了。 – ThreaT

+0

你沒有說的是,在最初的問題,在你的代碼片段,我只看到他們被用於在'StringBuilder'替代指標(其本身匹配可以做) – fge

+0

好吧,你是對的,對不起的人 – ThreaT

3

重新初始化在循環中的匹配。

刪除while循環中的matcher = pattern.matcher(temp);指令,您不應再被卡住了。

+0

它確實解決無限循環,但如果我拿出那條線,那麼'matcher'不會更新以使用新的'temp'字符串,所以它錯位了替換,因爲它得到'start'和'end'索引錯誤。 (它是從舊的'temp'字符串中識別匹配項和索引而不是新的) – ThreaT

+0

由於其他原因,您的代碼仍然存在錯誤,您需要查明。這只是解決了你所要求的「無限循環」。 –

+0

這個解決方案的工作原理,但它打破了別的東西,這意味着我必須恢復到一個無限循環,所以它還沒有解決...... – ThreaT

0

你爲什麼要使用Matcher呢?你不需要正則表達式來代替的話,只需要使用replace()

input.replace("oldtext", "newtext"); // replace all occurrences of old with new 
+0

它是找到它正在替換的字詞的索引 – ThreaT

+0

但是,這也將用'newtext'替換'iamoldtext' – fge

0

我固定它只需加入這一行:

if (!match.equals(changeWords(match))) { 
    matcher = pattern.matcher(temp); 
}