简体   繁体   English

Java从字符串中替换精确的子字符串

[英]Java replace exact substring from string

I have the following string: 我有以下字符串:

String str = "6,20,9,10,19,11,5,3,1,2";

and i want to replace the exact string ,2 or 1, to a empty string, avoiding that sub-string ,20 or 11, were involved into the replacement. 并且我想将确切的字符串,21,替换为空字符串,避免将子字符串,2011,包含在替换中。

i have this code: 我有这个代码:

// assuming that substr = ",2" or "1,"

if(str.startsWith(substr+",")){
    str = str.replace("^"+substr+",$","");
}               
else if(str.contains(","+substr+",")){
    str = str.replace("^"+substr+",$","");
}   
else if(str.endsWith(","+substr)){
    str = str.replace("^,"+substr+"$","");
}

but it seems that i am wrong with the regex. 但似乎我对正则表达式错了。 Which regex should i use to resolve it? 我应该使用哪个正则表达式来解决它?

My answer is: "What are you trying to acheive?" 我的回答是:“你想要实现什么?”

If you are trying to filter I'd go for String.split(",") and then filter the items generated in the string array. 如果你试图过滤我会去String.split(",") ,然后过滤字符串数组中生成的项目。 Eventually I'd join them (if you are not constrained by runtime). 最终我会加入它们(如果你不受运行时限制)。

Something like ( untested ): 像( 未经测试 )的东西:

String[] splits = myString.split(",");
// ... manipulate splits (filter into a list if you want...)
StringUtils.join(splits, ", "); // possibly replace with array from filtered list
  • splits can be replaced by filtered list's toArray 拆分可以由筛选列表的toArray替换

Solving it your way can be tricky. 以你的方式解决它可能会很棘手。 When you try and match an item you eliminate the chance to match it's neighbors. 当您尝试匹配项目时,您将无法匹配其邻居。 What you need to do is match aggregation. 您需要做的是匹配聚合。

This is just a start ( untested , based on this ): 这只是一个开始( 未经测试 ,基于 ):

    List<String> matches = new ArrayList<String>();
    Matcher m = Pattern.compile("(^[12],|,[12],|[12]$)").matcher("1,6,20,9,10,19,11,5,3,1,2");
    if (m.find()) {
        do {
            System.out.println("Matched "+m.group());
            matches.add(m.group());
        } while (m.find(m.start()+1));
    }

    for (String match : matches){
        System.out.println(match);
    }

You can try and profile run-time for both ways and maybe expand my answer later on :-) 您可以尝试两种方式运行时间,也可以稍后扩展我的答案:-)

I believe the question is "how to remove a value from the list", but only the exact value (eg 2 not 12, 13 not 413), and to shorten the list, ie to remove the preceding or following comma, if any, but not both. 我相信问题是“如何从列表中删除值”,但只有确切的值(例如2不是12,13而不是413),并缩短列表,即删除前面或后面的逗号,如果有的话,但不是两个。

Short Answer: 简答:

String x = Pattern.quote(textToRemove);
Pattern p = Pattern.compile("^"+x+"$|^"+x+",|,"+x+"$|,"+x+"(?=,)");
String output = p.matcher(input).replaceAll(""); // or replaceFirst

Examples: 例子:

Input:       "6,20,9,10,19,101,5,3,1,2"
Remove "2":  "6,20,9,10,19,101,5,3,1"   -- last value, don't remove 20
Remove "20": "6,9,10,19,101,5,3,1,2"    -- middle value
Remove "1":  "6,20,9,10,19,101,5,3,2"   -- don't remove 10, 19, or 101
Remove "10": "6,20,9,19,101,5,3,1,2"    -- don't remove 101
Remove "6":  "20,9,10,19,101,5,3,1,2"   -- first value
Remove "77": "6,20,9,10,19,101,5,3,1,2" -- nothing removed

Input:       "6"
Remove "6":  ""                         -- only value

Code: 码:

private static void test(String input, String textToRemove) {
    String rmv = Pattern.quote(textToRemove);
    Pattern p = Pattern.compile("^" + rmv + "$" +     // matches only value
                               "|^" + rmv + "," +     // matches first value + ','
                               "|," + rmv + "$" +     // matches ',' + last value
                               "|," + rmv + "(?=,)"); // matches ',' + middle value (+ ',')
    String output = p.matcher(input).replaceAll(""); // or replaceFirst
    System.out.printf("Remove %-4s from %-26s: %s%n",
                      '"' + textToRemove + '"',
                      '"' + input + '"',
                      '"' + output + '"');
}

Test: 测试:

public static void main(String[] args) throws Exception {
    //
    test("6,20,9,10,19,101,5,3,1,2", "2" );
    test("6,20,9,10,19,101,5,3,1,2", "20");
    test("6,20,9,10,19,101,5,3,1,2", "1" );
    test("6,20,9,10,19,101,5,3,1,2", "10");
    test("6,20,9,10,19,101,5,3,1,2", "6" );
    test("6,20,9,10,19,101,5,3,1,2", "77");
    test("6"                       , "6" );
}

Output: 输出:

Remove "2"  from "6,20,9,10,19,101,5,3,1,2": "6,20,9,10,19,101,5,3,1"
Remove "20" from "6,20,9,10,19,101,5,3,1,2": "6,9,10,19,101,5,3,1,2"
Remove "1"  from "6,20,9,10,19,101,5,3,1,2": "6,20,9,10,19,101,5,3,2"
Remove "10" from "6,20,9,10,19,101,5,3,1,2": "6,20,9,19,101,5,3,1,2"
Remove "6"  from "6,20,9,10,19,101,5,3,1,2": "20,9,10,19,101,5,3,1,2"
Remove "77" from "6,20,9,10,19,101,5,3,1,2": "6,20,9,10,19,101,5,3,1,2"
Remove "6"  from "6"                       : ""

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM