1

I want to create a regex, where the occurence of one group, depends on whether or not another certain group has been found. I think this is easier to illustrate with an example!

I want to allow two patterns, illustrated by these two examples: JsJh, JJ. This is not allowed: JsJs, JsJ, JQ.

So if the user types one small letter after the first capital one, the regex expects another small letter after the second capital - but it should not be the same letter as the first one!

I match the first (Js) like this: ([123456789TJQKA]){1}([dsch]?){1} The second capital letter is matched by (\\2).

Now, I cannot seem to find a solution for the last small letter. I can get the small letters to match (which is obv. not what I want), but how do I, if its present, exclude the first letter from the last group, by still allowing (and expecting) one of the three remaining small letters?

4
  • Does the duplicate detection have to be done in the regex? Why not parse card objects first then check them for equality? Commented Feb 8, 2010 at 22:50
  • I was thinking the same thing... But I think it's "cleaner" to use a regex for the whole thing. Or else, I just start having "else-if's" all over the place :) Commented Feb 8, 2010 at 22:59
  • Will the cards always be listed in a predetermined order? Or could the same hand be represented by Ac5JsJh or JhAcJs5 or whatever? Also, I notice you're matching both 1 and A as card values; don't those both refer to an Ace? Commented Feb 9, 2010 at 1:07
  • The 1 was a mistake, it should just be removed from the regex. The order should not matter! You should be able to write JhJc,A2s+,22+, 88-TT ... in the order you like. But the above regex is just for one token, seperated by comma. So the only situation where the order could matter, is when you apply a ceiling, like 22-55. (And write this as 55-22). But its easily fixed, with a call to Math.max() to find the ceiling. Commented Feb 9, 2010 at 12:47

1 Answer 1

1

Why are you using regular expressions to implement the logic of a card game? Seems pretty crazy... nevertheless it can be done!

s.matches("([123456789TJQKA])([dchs])\\1(?!\\2)[dchs]|([123456789TJQKA])\\3")

Here is a test to verify that it works correctly (and it also documents my assumptions about the special cases that you haven't covered in your question):

public class Test
{
    private static void test(String input, boolean expected)
    {
        boolean result = input.matches("([123456789TJQKA])([dchs])\\1(?!\\2)[dchs]|([123456789TJQKA])\\3");
        if (result != expected)
            throw new RuntimeException("Failed!");
    }

    public static void main(String[] args) throws Exception
    {
        test("JJ", true);
        test("JsJd", true);
        test("11", true);
        test("2c2h", true);

        test("Js", false);
        test("JsJs", false);
        test("JsJ", false);
        test("JQ", false);
        test("1d1d", false);
        test("J", false);
        test("", false);
        test("3d3d", false);
        test("JsJdJ", false);
        test("JsJdJh", false);
        test("1A", false);
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

The regex is just for parsing hand-ranges. So the user can type in eg. {A2s+, JJ+, 88, AKo, TsTh} as the distribution of hands his opponent might have. Your suggestion works wonders! Now I just need to find out what actually happens.
@Frederik, Just a few minor points: I managed to miss the T - oops! It's added now. Also as Anon. points out you can shorten 123456789 to 1-9.
Many thanks! I'm still wondering what the **** is going on though. This line: (?!\\2)[dchs]|([123456789TJQKA])\\3, what does it say? I cannot find anything about the '?!'-syntax anywhere. Maybe you have a good java regex reference? I cannot find many good resources. Sun's own seems... Not too comprehensive?
The (?! ... ) is a negative lookahead. See here: regular-expressions.info/lookaround.html

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.