0

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.

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?

2 Answers 2

2

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. 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

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

Sign up to request clarification or add additional context in comments.

4 Comments

but in this case i have to do a cycle to find the element, delete it and finally join all elements to re-build the string..i think the replace() method is faster or no?
depends on what you're trying to do. String manipulation is not very good for run-time, so I explicitly said this is a solution only if you are not constrained. If you can elaborate on your constraints, I'm sure a better fitting solution can be found.
i ask in fact if there is a particular regex to help me in this case or if i am wrong with the code I posted..
I've added more detail to my answer. I take no responsibility whatsoever.
0

I believe the question is "how to remove a value from the list", but only the exact value (e.g. 2 not 12, 13 not 413), and to shorten the list, i.e. to remove the preceding or following comma, if any, but not both.

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"                       : ""

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.