-4
//Its a question on replacement of duplicate characters

public class RemoveDuplicateChars {

    static String testcase1 = "DPMD Jayawardene";

    public static void main(String args[]){
        RemoveDuplicateChars testInstance= new RemoveDuplicateChars();
        String result = testInstance.remove(testcase1);
        System.out.println(result);

    }
    //write your code here
    public String remove(String str){
        return str.replaceAll("(.)(?=.*\\1)", "");//how this replacement working
    }       
}
Sotirios Delimanolis
  • 252,278
  • 54
  • 635
  • 683
user3229433
  • 33
  • 1
  • 5

2 Answers2

2

As you can see from the name of the class - it removes characters that repeat in a string.

Breakdown:
(.) - stands for any character, the brackets are used for grouping, so we'll be able to reference it later on using \1

(?=) - lookahead

(?=.*\\1) - we're looking forward
.* consuming any number of characters and looking for our first character\1

If the regex is truthy, the referenced character will be replaced with the empty string.

See Fiddle

Nir Alfasi
  • 49,889
  • 11
  • 75
  • 119
  • Does the `(` in front of `?=` start its own capture group? – Sotirios Delimanolis Feb 03 '14 at 20:13
  • @SotiriosDelimanolis yes it does, but in this case it would be same as `(.)` – Алексей Feb 03 '14 at 20:19
  • Nope. `(?=XXX)` will look forward for "XXX". The opening and closing brackets her are used as opening and closing tokens for the "look ahead" – Nir Alfasi Feb 03 '14 at 20:19
  • @alfasin if you redo w/ Pattern and Matcher you would end up with two groups; group(0) that corresponds to `(.)` and group(1) that correspond to positive look ahead – Алексей Feb 03 '14 at 20:22
  • @user1631616 are you sure it works with all flavors (that support lookahead) ? – Nir Alfasi Feb 03 '14 at 20:27
  • @alfasin positive/negative look ahead/behind def works with `Pattern/Matcher` as i used it for one of my projects. If you rewrite what OP has w/ Pattern/Matcher - you can see that whenever it matches there are 2 grps hence `Does the ( in front of ?= start its own capture group?` the answer is yes :) – Алексей Feb 03 '14 at 20:34
  • @user1631616 you ignored my question. I understand that it works in Java, but I doubt it'll work with other flavor of regex. That said, I'll definitely try it sometime soon with Python, Ruby, and JS - thanks! – Nir Alfasi Feb 03 '14 at 20:36
  • @alfasin i guess i miss understood your question (my bad) – Алексей Feb 03 '14 at 20:37
2

From java.util.Pattern:

  • (.) : Match any character in a capture group (basically a variable named \1)
  • (?= : Zero-width positive lookahead (make sure the rest of the string matches)
    • .* any number of characters followed by
    • \\1 the captured group

In other words, it matches any character that also appears later in the string (i.e. is a duplicate). In Java, this would be:

for(int i=0; i<str.length(); i++) { 
  char captured = str.charAt(i); // (.)
  if (str.substring(i+1).matches(".*" + captured))  { // (?=.*\1)
    // the char is a duplicate, replace it with "" 
  }
}
that other guy
  • 101,688
  • 11
  • 135
  • 166