PHP Regular Expression Request

I just tried to teach myself how to use regular expressions so sorry if this seems trivial to some.

I am doing a little crib script. He uses the standard deck of playing cards, and I use CDHS (clubs, diamonds, hearts, spades) for suits and A2..9TJQK (ace, 2 ... 9, 10, jack, queen, king) for takes.

I have a $hand variable, which is a line with even lines. For example, S2HA3D is 2 S2HA3D , an ace of hearts and 3 diamonds, respectively. Please note that the suit and rank can be in any order.

I use:

 preg_match_all("/[2-9ATJQK][CDHS]|[CDHS][2-9ATJQK]/i", $hand, $result); 

to find all the cards, but this returns the suits and ranks in the order found.

My question is, how can I get the result to give a ranking first for each card, regardless of the given order. I hope I have clearly stated this.

+6
source share
4 answers

I do not think that you can only do this with preg_match .

This function is intended to match strings, not to manipulate them. However, you can do preg_replace in the second pass:

 preg_match_all("/[2-9ATJQK][CDHS]|[CDHS][2-9ATJQK]/i", $hand, $rawResult); $normalisedResult = preg_replace('/([CDHS])([2-9ATJQK])/i', "$2$1", $rawResult[0]); 

If you're interested, $1 and $2 are backlinks to the groups indicated in parentheses in the first argument to preg_replace() .

+3
source

A way to use named captures with a J modifier that allows you to use the same names.

 $pattern = '~(?J)(?<rk>[2-9ATJQK])?(?<su>[CDHS])(?(1)|(?<rk>[2-9ATJQK]))~i'; preg_match_all($pattern, $hand, $matches, PREG_SET_ORDER); foreach($matches as $match) { $result .= $match['rk'] . $match['su']; } echo $result; 

Or easier with preg_replace:

 $result = preg_replace('~([2-9ATJQK])?([SCHD])(?(1)|([2-9ATJQK]))~i', '$2$1$3', $hand); 
+3
source

Edit: I did not receive your question correctly. here is what you need to do, you need to make 2 regular expression calls something like this:

 /([CDHS])([A2-9TJQK])/i 

then

 /([A2-9TJQK])([CDHS])/i 

try making a variable that can contain the value of the first group and the value of the second group. then in order to get the right rank you need to switch them with the second template ...

correct me if I am wrong, but you cannot do it with a single regex.

+1
source

I would use a regex to match all pairs, and then have some logic to re-evaluate the score as the first. Here is what I mean (untested)

 $grades = array(2,3,4,5,6,7,8,9,'A','T','J','Q','K'); preg_match_all('/((C|D|H|S)[2-9ATJQK]{1})|([2-9ATJQK]{1}(C|D|H|S))/i', $subject, $result, PREG_PATTERN_ORDER); for ($i = 0; $i < count($result[0]); $i++) { if (in_array($result[0][$i][0], $grades)) { echo ($result[0][$i]); } else { echo (strrev($result[0][$i])); } } 
0
source

Source: https://habr.com/ru/post/948244/


All Articles