一个正则表达式,用于匹配单个字符,后跟数字,以“c”结尾

I need a regex for the following pattern:

a single character from [e-g] followed by one or more numbers that ends with character 'c'.

for example e123f654g933c expected result:

Array
(
    [0] => Array
        (
            [0] => e123
            [1] => f654
            [2] => g933
        )

)

or

e123f654g933ce99f77g66c expected result:

Array
(
    [0] => Array
        (
            [0] => e123
            [1] => f654
            [2] => g933
        ),
    [1] => Array
        (
            [0] => e99
            [1] => f77
            [2] => g66
        )

)

I tried using the following but I don't know what to do with 'c' part. I used this ([e-g]{1}[0-9]{1,}c)+ but it fails.

$subject="e123f654g933ce99f786g776c";
preg_match_all('/[e-g]{1}[0-9]{1,}/', $subject, $match);
print '<pre>' . print_r($match,1) . '</pre>';

Array
(
    [0] => Array
        (
            [0] => e123
            [1] => f654
            [2] => g933
            [3] => e99
            [4] => f786
            [5] => g776
        )

)

thanks.

I couldn't manage to generate your multi dimensional output array via a single regex function call.

Code (Demo: https://3v4l.org/f5nnk )

$strings=[
    'e123f654g933c',
    'e123f654g933ce99f77g66c'
];

foreach($strings as $string){
    var_export(
        array_map(
            function($v){
                return preg_match_all('/[e-g]\d+/',$v,$out2)?$out2[0]:[];  // split the groups by string format
                // or return preg_split('/\d+\K/',$v,NULL,PREG_SPLIT_NO_EMPTY);
                // or return preg_split('/(?=[e-g])/',$v,NULL,PREG_SPLIT_NO_EMPTY);

            },
            preg_match_all('/(?:[e-g]\d+)+(?=c)/',$string,$out1)?$out1[0]:[]  // split into groups using c
            // or explode('c',rtrim($string,'c'))
            // or array_slice(explode('c',$string),0,-1)
            // or preg_split('/c/',$string,NULL,PREG_SPLIT_NO_EMPTY)
        )
    );
    echo"

";
}

Output:

array (
  0 => 
 array (
    0 => 'e123',
    1 => 'f654',
    2 => 'g933',
  ),
)

array (
  0 => 
  array (
    0 => 'e123',
    1 => 'f654',
    2 => 'g933',
  ),
  1 => 
  array (
    0 => 'e99',
    1 => 'f77',
    2 => 'g66',
  ),
)

It seems you are looking for

[e-g]\d+


This needs to be matched and extracted in PHP like so...
<?php

$strings = ['e123f654g933c', 'e123f654g933ce99f77g66c'];

$regex = '~[e-g]\d+~';

foreach ($strings as $string) {
    if (preg_match_all($regex, $string, $matches)) {
        print_r($matches[0]);
    }
}
?>


... and yields
Array
(
    [0] => e123
    [1] => f654
    [2] => g933
)
Array
(
    [0] => e123
    [1] => f654
    [2] => g933
    [3] => e99
    [4] => f77
    [5] => g66
)

You may use

'~(?:\G(?!^)|(?=(?:[e-g]\d+)+c))[e-g]\d+~'

See the regex demo. In short, due to the (?:\G(?!^)|(?=(?:[e-g]\d+)+c)) part, [e-g]\d+ will only match when in between 1 or more occurrences of [e-g]\d+ and c.

Details

  • (?:\G(?!^)|(?=(?:[e-g]\d+)+c)) - match the end of the last successful match (\G(?!^)) or (|) the location followed with an e, f or g letter followed with 1+ digits, 1+ occurrences (due to the(?=(?:[e-g]\d+)+c) positive lookahead)
  • [e-g]\d+ - an e, f or g letter followed with 1+ digits

PHP demo:

$re = '/(?:\G(?!^)|(?=(?:[e-g]\d+)+c))[e-g]\d+/';
$str = 'e123f654g933c and e123f654g933ce99f77g66c';
preg_match_all($re, $str, $matches);
print_r($matches[0]);
// => Array ( [0] => e123 [1] => f654 [2] => g933 [3] => e123 [4] => f654 [5] => g933 [6] => e99 [7] => f77 [8] => g66 )

You can't easily achieve this with a single RegExp. The solution is to split the string at the occurrences of 'c', handle the parts separately, and then build the result array:

<?php

$strings = [
    'e123f654g933c',
    'e123f654g933ce99f77g66c',
];

foreach ($strings as $input)
{
    print_r(match($input));
}

function match($input)
{
    $result = [];
    $parts  = array_filter(explode('c', $input));

    foreach ($parts as $part)
    {
        preg_match_all('~[e-g]\d+~', $part, $matches);
        $result[] = $matches[0];
    }

    return $result;
}

The output will be

Array
(
    [0] => Array
        (
            [0] => e123
            [1] => f654
            [2] => g933
        )
)

Array
(
    [0] => Array
        (
            [0] => e123
            [1] => f654
            [2] => g933
        )
    [1] => Array
        (
            [0] => e99
            [1] => f77
            [2] => g66
        )
)