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 String.replaceAll regex
  • java String.replaceAll regex question
  • Java 1.3 String.replaceAll() , replace

您可以在 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字符串文字)

,b11b|b11b,

这将确保由于单词边界,11 不会作为另一个数字的一部分进行匹配,并且只有一个逗号(如果存在两个逗号)被匹配并删除。

你可以构建一个正则表达式,比如

^11,|,11b

这将匹配字符串(^11,)或(|)开头的11,,11后不跟任何其他单词char(,11b)。

请参阅正则表达式演示。

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

试试这个:

String result = css#.replaceAll("," + elimiateUserId, "")
.replaceAll(elimiateUserId + "," , "");

您可以在一次拍摄中使用两个替换,例如:

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

IDEe演示

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左右时

最新更新