3
String[] words = {"a","ab","ac","abc","aac","aa"};
for(String str:words)   {
    if(str.matches("[abc]+"))  {
        System.out.println(str);
    }
}

This code print out

a,ab,ac,abc,aac,aa

This is almost what I want except I do not want a letter be matched twice. I want to change the regex [abc]+ so that the match will only happen once. The aac and aa should not printed because aa is matched twice. Can I do this?

Tony
  • 603
  • 5
  • 9
  • 17
  • Do you only have 3 single chars in real life scenario? If yes, and the example above is a very simplified example of what is really needed, then regex is not the best tool for this task. – Wiktor Stribiżew Nov 21 '16 at 20:02
  • 2
    Unless there's an artificial requirement to use a regular expression, I'd say you're way better off doing this procedurally by creating a method that iterates over the characters in the string and puts them into a `Set`, failing if it detects a duplicate (if [Set.add](https://docs.oracle.com/javase/7/docs/api/java/util/Set.html#add\(E\)) returns false). – dnault Nov 21 '16 at 20:02
  • 5
    I think your issue is similar to : http://stackoverflow.com/questions/12870489/regex-to-match-a-word-with-unique-non-repeating-characters – xBATx Nov 21 '16 at 20:05
  • 3
    What about "aca"? – Frank Puffer Nov 21 '16 at 20:06
  • This sounds like a problem for negative lookahead - not pure regexp –  Nov 21 '16 at 20:08
  • 3
    Not everything that can be done with a regex should be. – user2357112 Nov 21 '16 at 20:11
  • @xBATx, thank you - starting the closing process –  Nov 21 '16 at 20:22

3 Answers3

2

Using negative lookahead you can use this regex:

^(?:([abc])(?!.*\1))+$

RegEx Demo

If you want to allow any character not just [abc] then use:

^(?:(.)(?!.*\1))+$
  • (.) matches and groups any character
  • (?!.*\1) is negative lookahead that asserts for each character captured, that the same character does not exist ahead of the current position.
  • (?:...)+ groups matching character and lookahead in a non-capturing group which is repeated 1 or more times to match whole string.
anubhava
  • 761,203
  • 64
  • 569
  • 643
0

If you really want a Regex and if you're only allowed to use [abc], it's pretty easy to check all the possibilities :D.

String[] words = { "a", "ab", "ac", "abc", "aac", "aa" };
for (String str : words) {
    if (str.matches("(abc|ab|acb|ac|a|bac|ba|bca|bc|b|cab|ca|cba|cb|c)")) {
        System.out.println(str);
    }
}

Otherwise, you could check if the String matches [abc]+ but doesn't contain "([a-c]).*\\1"

Eric Duminil
  • 52,989
  • 9
  • 71
  • 124
0

Is ab?c? what you're looking for?

primfaktor
  • 2,831
  • 25
  • 34