Java:String.replaceAll(regex,replacement);

时间:2017-06-29 14:10:14

标签: java regex string replace replaceall

我有一串逗号分隔的用户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

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

10 个答案:

答案 0 :(得分: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

答案 1 :(得分:5)

如果你想使用正则表达式,你可以使用(记得正确转义为java字符串文字)

,\b11\b|\b11\b,

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

答案 2 :(得分:5)

您可以构建像

这样的正则表达式
^11,|,11\b

将在字符串(11,)或(^11,|的开头匹配,11,而不会跟随任何其他字词char(,11\b )。

请参阅regex demo

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 demo

答案 3 :(得分:4)

尝试将(^(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

答案 4 :(得分: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 demo

答案 5 :(得分:3)

试试这个:

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

答案 6 :(得分:3)

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.

单词边界标记,匹配&#34;单词&#34;的开头或结尾,在这里是神奇的。这意味着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.

&#34; if&#34;这里的部分有点不寻常 - 你可以在这里找到关于正则表达式条件的更多信息:http://www.regular-expressions.info/conditional.html

我不确定Java是否支持正则表达式条件。这里的一些帖子(Conditional Regular Expression in 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编译器)

这将足够快(最坏情况下,对于来自一串n个ID的m个删除大约为O(m * n)),但我们可以做得更好。

一种是将正则表达式构建为\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列表要删除,无论如何,因为它会很多更丑陋和更复杂的代码)。

答案 7 :(得分:1)

我认为维护白名单更安全,然后将其用作进一步更改的参考。

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);

答案 8 :(得分:0)

如果您需要使用Regex的解决方案,那么以下工作非常有效。

    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(",$", "");

我使用您想要的所有类型的输入。

答案 9 :(得分:-2)

这应该有效

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

至少可以保证什么时候没有311,或者113左右