Remove last repetitive characters of a string

java, regex, string

Solution

I would not use a regex:

public class Test {
  public void test() {
    System.out.println(removeTrailingDupes("abcdaaaaefghaaaaaaaaa"));
    System.out.println(removeTrailingDupes("012003400000000"));
    System.out.println(removeTrailingDupes("0120034000000001"));
    System.out.println(removeTrailingDupes("cc"));
    System.out.println(removeTrailingDupes("c"));
  }

  private String removeTrailingDupes(String s) {
    // Is there a dupe?
    int l = s.length();
    if (l > 1 && s.charAt(l - 1) == s.charAt(l - 2)) {
      // Where to cut.
      int cut = l - 2;
      // What to cut.
      char c = s.charAt(cut);
      while (cut > 0 && s.charAt(cut - 1) == c) {
        // Cut that one too.
        cut -= 1;
      }
      // Cut off the repeats.
      return s.substring(0, cut);
    }
    // Return it untouched.
    return s;
  }

  public static void main(String args[]) {
    new Test().test();
  }
}

To match @JonSkeet's "spec":

Note that this will only remove characters that are duplicated at the end. That means single character strings will not be touched but two-character strings could become empty if both characters are the same:

"" => ""
"x" => "x"
"xx" => ""
"aaaa" => ""
"ax" => "ax"
"abcd" => "abcd"
"abcdddd" => "abc"

I wonder if it would be possible to achieve that level of control in a regex?

Added as a result of the ... but If we use this regex with aaaa for example, it returns nothing. It should return aaaa. comment:

Instead, use:

  private String removeTrailingDupes(String s) {
    // Is there a dupe?
    int l = s.length();
    if (l > 1 && s.charAt(l - 1) == s.charAt(l - 2)) {
      // Where to cut.
      int cut = l - 2;
      // What to cut.
      char c = s.charAt(cut);
      while (cut > 0 && s.charAt(cut - 1) == c) {
        // Cut that one too.
        cut -= 1;
      }
      // Cut off the repeats.
      return cut > 0 ? s.substring(0, cut): s;
    }
    // Return it untouched.
    return s;
  }

which has the contract:

"" => ""
"x" => "x"
"xx" => "xx"
"aaaa" => "aaaa"
"ax" => "ax"
"abcd" => "abcd"
"abcdddd" => "abc"

Problem

Let's say we have a String like these ones : ``` "abcdaaaaefghaaaaaaaaa" "012003400000000" ``` I would like to remove the last repetitive characters, to obtain this : ``` "abcdaaaaefgh" "0120034" ``` Is there a simple way to do this, with regex ? I am kind of having hard times with this and my code begin to look like a gigantic monster... Some clarification : What is considered as repetitive ? A sequence of at least 2 characters at the end. One character is not considered as repeated. For instance : in `"aaaa"`, `'a'` is not considered as repetitive, but in `"baaaa"`, it is. So in the case of `"aaaa"`, we don't have to change anything to the String. Another instance : `"baa"` must give `"b"`. And for Strings of only one character ? A string like `"a"`in which we only have the char `'a'` must be returned without changing anything, i.e. we must return `"a"`.

Original source