none
regex pattern help RRS feed

  • Question

  • Hi all,

    I am trying to use regex to determine card hands in poker (texas holdem)

    If Regex.IsMatch(player_string, "3[a-t_1-9]{1}") Then
                MsgBox("3 of a kind")
            ElseIf Regex.IsMatch(player_string, "2[a-t_1-9]{2}") Then
                MsgBox("2 pair")
            ElseIf Regex.IsMatch(player_string, "2[a-t_1-9]{1}") Then
                MsgBox("single pair")
            End If

    However it incorrectly matches and shows a msgbox when there are no pairs (overall, does not work)

    What should the pattern be?? I am new to regex so forgive me if this is a noob type question ;)

    the string passed to it (player_string) is made up of single digit/letters of the players 2 cards plus the dealers 5 (i.e. a 2, 3, 5, 6, jack, king, 10 would equal a string of: 2356jkt)

    Any help is appreciated!

    thanks for your time,

    Josh

    Sunday, July 22, 2012 5:48 AM

Answers

  • I think you need to use backreferences.  I have never used them before, so I'll leave the tryout to you.  http://www.regular-expressions.info/refadv.html.  I think something along the lines ([2-9TJQKA])\1\1 for 3 of a kind, one less backreference for a pair, etc.

    NOTE:  You may need to pre-sort the string for the RegEx to work.


    Jose R. MCP
    Code Samples



    • Edited by webJose Sunday, July 22, 2012 8:33 PM
    • Proposed as answer by Mike FengModerator Monday, July 23, 2012 10:24 AM
    • Marked as answer by jmonkey610 Tuesday, July 24, 2012 9:05 AM
    Sunday, July 22, 2012 7:11 PM
  • Having the string 23656KT you should be able to extract the pair of sixes there.  BUT if you try you'll fail.  This is because the RegEx is not programmed to search a match on every other possible position in the string.  The RegEx I gave you requires immediate repetition.  Therefore the string needs to be re-written as 23566TK (sorted by value) so the sixes are next to each other.

    Jose R. MCP
    Code Samples

    • Marked as answer by jmonkey610 Tuesday, July 24, 2012 9:05 AM
    Monday, July 23, 2012 1:27 PM

All replies

  • I think you need to use backreferences.  I have never used them before, so I'll leave the tryout to you.  http://www.regular-expressions.info/refadv.html.  I think something along the lines ([2-9TJQKA])\1\1 for 3 of a kind, one less backreference for a pair, etc.

    NOTE:  You may need to pre-sort the string for the RegEx to work.


    Jose R. MCP
    Code Samples



    • Edited by webJose Sunday, July 22, 2012 8:33 PM
    • Proposed as answer by Mike FengModerator Monday, July 23, 2012 10:24 AM
    • Marked as answer by jmonkey610 Tuesday, July 24, 2012 9:05 AM
    Sunday, July 22, 2012 7:11 PM
  • Hi,

    As webJose mentioned without sorting it won't work at all. But one question came to my head: how do you handle the different colors? You will need this info for some combinations, but the player_string doesn't contain it at all.

    By the way why don't you create a card class which can contain the card value and the color? You should store the cards in generic lists instead of strings, and I think it would be much easier to find different combinations too...

    Monday, July 23, 2012 9:20 AM
  • Since you need to handle card suits, you're better off using a delimiter

    2C,3D,5H,6S,JD,KH,TC

    That said, Expresso is a great tool for building/testing .Net regular expressions.  You can get it from  http://www.ultrapico.com/


    This signature unintentionally left blank.

    Monday, July 23, 2012 10:45 AM
  • Hi all, thanks for the replies,

    I have been trying to use the back-references however still haven't found the right pattern. Can you expand a bit?? struggling a bit with the pattern :(

    Thank you for the link to espresso, very helpful tool :)

    In regards to suit, each card in the deck has a structure with its value, image and suit. player_string is created from this array and so it shouldn't be to hard to check suit.

    What do you mean by sorting?? I thought regex simply searched as par the pattern and order is ignored???

    Thanks for all your help!, keep it coming!

    Josh

    Monday, July 23, 2012 1:15 PM
  • Having the string 23656KT you should be able to extract the pair of sixes there.  BUT if you try you'll fail.  This is because the RegEx is not programmed to search a match on every other possible position in the string.  The RegEx I gave you requires immediate repetition.  Therefore the string needs to be re-written as 23566TK (sorted by value) so the sixes are next to each other.

    Jose R. MCP
    Code Samples

    • Marked as answer by jmonkey610 Tuesday, July 24, 2012 9:05 AM
    Monday, July 23, 2012 1:27 PM
  • Brilliant!

    thank you so much, all works now :) now I only need to work out striaghts, flushes etc :D

    Code for the pairs and simple ones if anyone else wants to know:

    If Regex.IsMatch(player_string, "([1-9tjqk])\1\1") And Regex.IsMatch(player_string, "([1-9tjqk])\1") Then
                MsgBox("full-house")
            ElseIf Regex.IsMatch(player_string, "([1-9tjqk])\1\1") Then
                MsgBox("3 of a kind")
            ElseIf Regex.Matches(player_string, "([1-9tjqk])\1").Count >= 2 Then
                MsgBox("2 pair")
            ElseIf Regex.IsMatch(player_string, "([1-9tjqk])\1") Then
                MsgBox("single pair")
            End If

    Thnaks for all the help!

    Tuesday, July 24, 2012 9:07 AM
  • Hi again, just wondered if I could trouble you for one more quick question,

    how do you make a pattern to: match first pattern then match a second however it cannot be matched from the first match (i.e. full-house, 3 cards and a pair)

    My current attempt using [^]:

    ElseIf Regex.IsMatch(check_string, "(([1-9tjqk])\1\1) ([^1-9tjqk ][1-9tjqk ]\1)") Then

    MsgBox("fullhouse")

    I'm reasonably sure its a long way off ;)

    Sorry to keep it going :(

    Thanks,

    josh

    Tuesday, July 24, 2012 12:38 PM