2017-06-21 56 views
0

我有一個字符串,12999986, 31999999, 39949283, 99002999其中我試圖用模式00替換所有的模式99。但是,該模式不能是另一個類似字符串的子字符串的一部分,如9999999。在此示例中,輸出將爲12999986, 31999999, 30049283, 000029993994928330049283,9900299900002999)。我創建了這個方法,但它並沒有真正較大的字符串的工作(沒有找到的所有模式,插入串在隨機的地方):只替換不是相似字符串的子串的字符串?

public static String replaceAllExact(String data, String searchString, String replacement) { 
    List<Integer> locations = new ArrayList<>(); //start (exclusive) 
    char[] dataChars = data.toCharArray(); 
    char[] searchStringChars = searchString.toCharArray(); 
    char[] replacementChars = replacement.toCharArray(); 

    int i = 0; 
    int k = 0; 
    int startIndex = 0; 
    int searchStringCharsLength = searchStringChars.length - 1; 

    for(char c : dataChars) { 
     if(c != searchStringChars[i] && i == 0) { //not the start of a pattern; continue 
      k++; 
      continue; 
     }else if(c == searchStringChars[i] && i == 0) { //might be the pattern we're looking for 
      startIndex = k; 
      i++; 
     }else if((c == searchStringChars[i] && i > searchStringCharsLength) || ((c != searchStringChars[i] && i < searchStringCharsLength) && i != 0)) { //pattern was too long or too short to be the pattern we're looking for 
      i = 0; 
     }else if(c == searchStringChars[i] && i < searchStringCharsLength) { //could be the pattern... keep going 
      i++; 
     }else if(c != searchStringChars[i] && i != 0 && i == searchStringCharsLength) { //this is the pattern we're looking for 
      locations.add(startIndex); 
      i = 0; 
     } 

     k++; 
    } 

    int offset = 0; 
    StringBuilder builder = new StringBuilder(data); 

    for(int l : locations) { 
     l += offset; 
     builder.delete(l, l + searchString.length()); 
     builder.insert(l, replacementChars); 
     offset = (builder.length() - data.length()); 
    } 

    return builder.toString(); 
} 

我怎樣才能做到這一點?如果可能的話,正則表達式解決方案將受到歡迎。

澄清

類似的字符串是一個字符串,其中一個正常替換將取代的某些字符。例如,使用標準庫replace(CharSequence target, CharSequence replacement),字符串31999999將被視爲相似,因爲replace(99, 00)可以替換某些字符。

字符串39349283不是類似的字符串,因爲replace(99, 00)不能替換任何字符。字符串39949283是相似的,因爲replace(99, 00)可以替換某些字符。

+0

你能解釋一下嗎?我現在閱讀它的方式聽起來像你想要替換字符串中的子字符串,其中你的字符串不包含在你的字符串的另一個子字符串中,這意味着它永遠不會被替換 - 因爲子字符串幾乎總是成爲一個部分一個更大的子字符串給定的大小允許它。這只是重複的字符,就像在你的例子中一樣? –

+0

我想我的問題是 - 什麼構成了類似的字符串? –

+0

@EastonBornemeier兩連續的9s換成兩個連續的0s,但如果超過兩個連續的話,他不希望它們被替換。 –

回答

2

如果我正確理解你,你想用其他東西替換99,但前提是前後沒有9

在這種情況下,你可以使用look-around機制,確保

  • 之前沒有9,通過(?<!9)
  • 後,仍然沒有9,通過(?!9)

所以,你可以使用str = str.replaceAll("(?<!9)99(?!9)", "00")

+0

我不認爲這個問題是特定於99的,而是一般的模式。 – Noobgineer

+0

@Noobgineer同意,但解決方案可以很容易地更改爲與其他案件一起使用。真正的解決方案取決於OP真正想實現的目標。 – Pshemo

+0

@Noobgineer在這種情況下,您可以相應地調整正則表達式。 – Andreas