Frederik Wordenskjold
Frederik Wordenskjold

Reputation: 10241

Java regex; conditions on groups

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?

Upvotes: 1

Views: 1338

Answers (1)

Mark Byers
Mark Byers

Reputation: 839224

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);
    }
}

Upvotes: 1

Related Questions