I want to match all 1 digit and 2 digit numbers using regex.
Subject string: '12345'
Expected match: 1,2,3,4,5,12,23,34,45
I'm trying: \d(\d)?
but as result i get 12,2,34,3,5
CodePudding user response:
You can use
$s = "12345";
$res = [];
if (preg_match_all('~(?=((\d)\d?))~', $s, $m, PREG_SET_ORDER)) {
$single = []; $double = [];
foreach ($m as $v) {
if ($v[1] != $v[2]) {
array_push($single, $v[2]);
array_push($double, $v[1]);
} else {
array_push($single, $v[1]);
}
}
$res = array_merge($single, $double);
print_r( $res );
}
See the PHP demo. Output:
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 12
[6] => 23
[7] => 34
[8] => 45
)
NOTES:
(?=((\d)\d?))
- a regex that captures into Group 1 two or one digits, and into Group 2 the first digit of the previous sequencePREG_SET_ORDER
groups the captures into the same parts of the match array- If the match is a single digit, the
$double
array is not modified - The final array is a combination of single digit array double digit array.
CodePudding user response:
I'm not so sure this can be done with regex as it will match 2 OR 1, then move on through the string.
So if it finds "12" at position 0, it will move to position 1 and find "2".
But if it finds "1" at position 0, it will move to position 1 and find "2" and never see "12".
I'm not sure if what it finds is random or not.
You can acheieve this with some PHP code though.
Loop through the characters and at each position ask...
Is this character numeric? If yes add to array.
Is this character and the next character numeric? If yes, concat both and add to array.
Then move to next position.
<?php
$string = '12345f67';
$chars = str_split($string);
$length = count($chars);
$numbers = [];
for ($i = 0; $i < $length; $i ) {
if (is_numeric($chars[$i])) {
$numbers[] = (int) $chars[$i];
if ($i < ($length - 1) && is_numeric($chars[$i 1])) {
$numbers[] = (int) ($chars[$i].$chars[$i 1]);
}
}
}
print_r($numbers);
Results below of above code....
Array
(
[0] => 1
[1] => 12
[2] => 2
[3] => 23
[4] => 3
[5] => 34
[6] => 4
[7] => 45
[8] => 5
[9] => 6
[10] => 67
[11] => 7
)
CodePudding user response:
Here is a straightforward solution:
$digits = '12345';
preg_match_all('/\d/', $digits, $single_digit_matches);
preg_match_all('/\d\d/', $digits, $two_digit_matches1);
preg_match_all('/\d\d/', substr($digits, 1), $two_digit_matches2);
$matches = array_merge($single_digit_matches[0], $two_digit_matches1[0], $two_digit_matches2[0]);
asort($matches);
print_r($matches);
The output is
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 12
[7] => 23
[6] => 34
[8] => 45
)