![](/img/trans.png)
[英](Java) How to mimic a regex in the “replacement” argument of String.replaceAll()?
[英]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
嘗試這個:
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.