簡體   English   中英

Java:String.replaceAll(regex,替換);

[英]Java: String.replaceAll(regex, replacement);

我有一個用逗號分隔的用戶ID字符串,我想從字符串中刪除/刪除特定的用戶ID。

我正在跟蹤字符串的可能性並期望結果

int elimiateUserId = 11;

String css1 = "11,22,33,44,55";
String css2 = "22,33,11,44,55";
String css3 = "22,33,44,55,11";
// The expected result in all cases, after replacement, should be:
// "22,33,44,55"

我嘗試了以下方法:

String result = css#.replaceAll("," + elimiateUserId, "");  // # =  1 or 2 or 3
result = css#.replaceAll(elimiateUserId + "," , "");

如果使用css3此邏輯失敗。 請建議我針對此問題的適當解決方案。

注意 :我正在使用Java 7

我檢查了以下帖子,但找不到任何解決方案:

您可以在Java 8中使用Stream API:

int elimiateUserId = 11;
String css1 = "11,22,33,44,55";

String css1Result = Stream.of(css1.split(","))
    .filter(value -> !String.valueOf(elimiateUserId).equals(value))
    .collect(Collectors.joining(","));

// css1Result = 22,33,44,55

如果要使用正則表達式,則可以使用(請記住,以Java字符串文字形式正確轉義)

,\b11\b|\b11\b,

這將確保由於單詞邊界而不會將11作為另一個數字的一​​部分進行匹配,並且僅會匹配並刪除一個逗號(如果存在兩個逗號)。

您可以構建一個正則表達式

^11,|,11\b

在字符串( ^11, )或( |,11的開頭將匹配11,之后不跟其他任何字符char( ,11\\b )。

參見regex演示

int elimiate_user_id = 11;
String pattern = "^" + elimiate_user_id + ",|," + elimiate_user_id + "\\b";
System.out.println("11,22,33,44,55,111".replaceAll(pattern, "")); // => 22,33,44,55,111
System.out.println("22,33,11,44,55,111".replaceAll(pattern, "")); // => 22,33,44,55,111 
System.out.println("22,33,44,55,111,11".replaceAll(pattern, "")); // => 22,33,44,55,111

參見Java演示

嘗試(^(11)(?:,))|((?<=,)(11)(?:,))|(,11$)表達式replaceAll

final String regexp = MessageFormat.format("(^({0})(?:,))|((?<=,)({0})(?:,))|(,{0}$)", elimiateUserId)
String result = css#.replaceAll(regexp, "") //for all cases.  

這是一個示例: https : //regex101.com/r/LwJgRu/3

您可以像這樣使用兩次替換:

int elimiateUserId = 11;
String result = css#.replace("," + elimiateUserId , "").replace(elimiateUserId + ",", "");

如果您的字符串是,11 ,則第一個替換項將替換為空
如果您的字符串是11,則第二個替換將替換為空

結果

11,22,33,44,55      ->     22,33,44,55
22,33,11,44,55      ->     22,33,44,55
22,33,44,55,11      ->     22,33,44,55

ideone演示

嘗試這個:

String result = css#.replaceAll("," + elimiateUserId, "")
             .replaceAll(elimiateUserId + "," , "");
String result = css#.replaceAll("," + eliminate_user_id + "\b|\b" + eliminate_user_id + ",", '');

這里的正則表達式是:

,     A leading comma.
eliminate_user_id  I assumed the missing 'n' here was a typo.
\b    Word boundary: word/number characters end here.
|     OR
\b    Word boundary: word/number characters begin here.
eliminate_user_id again.
,     A trailing comma.

匹配“單詞”開頭或結尾的單詞邊界標記是這里的魔力。 這意味着11將在以下字符串中匹配:

11,22,33,44,55
22,33,11,44,55
22,33,44,55,11 

但不是這些字符串:

111,112,113,114
411,311,211,111

不過,有一種更清潔的方法:

String result = css#.replaceAll("(,?)\b" + eliminate_user_id + "\b(?(1)|,)", "");

這里的正則表達式是:

(     A capturing group - what's in here, is in group 1.
,?    An optional leading comma.
)     End the capturing group.
\b    Word boundary: word/number characters begin here.
eliminate_user_id  I assumed the missing 'n' here was a typo.
\b    Word boundary: word/number characters end here.
(?(1) If there's something in group 1, then require...
|     ...nothing, but if there was nothing, then require...
,     A trailing comma.
)     end the if.

這里的“ if”部分有點不尋常-您可以在這里找到有關正則表達式條件的更多信息: http : //www.regular-expressions.info/conditional.html

我不確定Java是否支持正則表達式條件。 這里的一些帖子( Java中的條件正則表達式? )建議它不:(


旁注:為了提高性能,如果列表很長並且要執行很多刪除操作,最明顯的選擇是對每個要刪除的數字運行上面的行:

String css = "11,22,33,44,55,66,77,88,99,1010,1111,1212,...";
Array<String> removals = ["11", "33", "55", "77", "99", "1212"];
for (i=0; i<removals.length; i++) {
  css = css.replaceAll("," + removals[i] + "\b|\b" + eliminate_user_id + ",", "");
}

(未經測試的代碼:此處無法訪問Java編譯器)

這將足夠快(最壞的情況下縮放比例約為O(m * n),用於從n個id的字符串中去除m個),但是我們可以做得更好。

一種是將正則表達式構建為\\b(11,42,18,13,123,...etc)\\b也就是說,使正則表達式搜索要同時刪除的所有ID。 從理論上講,這種縮放比例會稍差一些,在每種情況下均以O(m * n)進行縮放,而不是在最壞的情況下進行縮放,但實際上應該更快。

String css = "11,22,33,44,55,66,77,88,99,1010,1111,1212,...";
Array<String> removals = ["11", "33", "55", "77", "99", "1212"];
String removalsStr = String.join("|", removals);
css = css.replaceAll("," + removalsStr + "\b|\b" + removalsStr + ",", "");

但是另一種方法可能是建立長字符串中ID的哈希表,然后從哈希表中刪除所有ID,然后將其余哈希表鍵連接回字符串中。 由於哈希表查找對於稀疏哈希表實際上是O(1),因此可以使用O(n)進行擴展。 不過,這里的權衡是該哈希表的額外內存。

(我認為沒有Java編譯器就無法實現此版本。除非您有要刪除的VAST(成千上萬)ID列表,否則我不建議您使用此方法,因為這將使代碼更加丑陋和復雜)。

我認為維護白名單,然后將其用作進行進一步更改的參考更為安全。

List<String> whitelist = Arrays.asList("22", "33", "44", "55");
String s = "22,33,44,55,11";
String[] sArr = s.split(",");
StringBuilder ids = new StringBuilder();
for (String id : sArr) {
    if (whitelist.contains(id)) {
        ids.append(id).append(", ");
    }
}
String r = ids.substring(0, ids.length() - 2);
System.out.println(r);

如果您需要使用正則表達式的解決方案,那么以下方法非常適用。

    int elimiate_user_id = 11;

    String css1 = "11,22,33,44,55";
    String css2 = "22,33,11,44,55";   
    String css3 = "22,33,44,55,11";

    String resultCss=css1.replaceAll(elimiate_user_id+"[,]*", "").replaceAll(",$", "");

我可以處理您想要的所有類型的輸入。

這應該工作

replaceAll("(11,|,11)", "")

至少可以保證何時沒有311或,113左右

暫無
暫無

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

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