我有一个逗号分隔的用户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左右时