regex 将3个字母的month替换为字符串数组中的月份号

xzlaal3s  于 2023-01-18  发布在  其他
关注(0)|答案(3)|浏览(133)

在数组中搜索字符串的第一个匹配项,直到空格为止,然后将其转换为month。

$arr = [
 "May Hello",
 "Jun Hello12",
 "Jul 3"
];

$str =  $arr[0];
$matches = [];
$pattern = '/^\w+\s/';
preg_match_all($pattern, $str, $matches);

替换$arr中的$pattern:

$pattern = [
 '/^\w+\s/' => date('m', strtotime($matches[0][0])) . ' ', // fist string until space
];
$arr = preg_replace(array_keys($pattern), array_values($pattern), $arr);

echo '<pre>';
print_r($arr);
echo '</pre>';

非预期:

Array
(
    [0] => 05 7 Hello
    [1] => 05 Hello12
    [3] => 05 3
)

预期:

Array
(
    [0] => 05 7 Hello
    [1] => 06 Hello12
    [3] => 07 3
)

我哪里做错了?

wnvonmuf

wnvonmuf1#

当你想对匹配的结果运行一个函数时,你应该使用preg_replace_callback

$arr = [
 "May Hello",
 "Jun Hello12",
 "Jul 3"
];

$arr = preg_replace_callback(
        '/^(\w+)\s/',
        function ($matches) {
            return date('m', strtotime($matches[0])).' ';
        },
        $arr
    );

echo '<pre>';
print_r($arr);
echo '</pre>';

输出:

Array
(
    [0] => 05 Hello
    [1] => 06 Hello12
    [2] => 07 3
)
piah890a

piah890a2#

在模式中使用单词边界来确保在字符串的开头只找到一个3个字母的单词。在闭包中,可以将完整的字符串匹配转换为用零填充的月份数字,并省略尾部空格的连接。
代码:(Demo

var_export(
    preg_replace_callback('/^[A-Z][a-z]{2}\b/', fn($m) => date('m', strtotime($m[0])), $arr)
);

根据输入的字符串,如果3个字母的月份的字母保证不会出现在字符串的后面,那么可以创建一个转换数组并调用strtr()以避免使用regex。

$trans = [
    'Jan' => '01',
    'Feb' => '02',
    'Mar' => '03',
    'Apr' => '04',
    'May' => '05',
    'Jun' => '06',
    'Jul' => '07',
    'Aug' => '08',
    'Sep' => '09',
    'Oct' => '10',
    'Nov' => '11',
    'Dec' => '12'
];

foreach ($arr as $v) {
    echo strtr($v, $trans) . "\n";
}
rwqw0loc

rwqw0loc3#

$len = count($arr);

    for ($i=0; $i<$len; $i++) {
        $element = $arr[$i];
        $letterMonth = substr($element, 0, 3);
        $dateObj = \DateTime::createFromFormat('F', $letterMonth);
        $month = $dateObj->format('m');
        $arr[$i] = str_replace($letterMonth, $month, $element );
    }

    return $arr;

相关问题