Замените трехбуквенный месяц на его номер месяца в массиве строк

Найдите в массиве первое вхождение строки до пробела, а затем преобразуйте его в месяц.

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

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

Замените $pattern в $arr:

$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
)

Что я делаю не так?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
74
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Вы должны использовать 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
)

Используйте границу слова в шаблоне, чтобы убедиться, что в начале строки находится только слово из 3 букв. В замыкании вы можете преобразовать совпадение полной строки в номер месяца, дополненный нулями, и опустить конкатенацию завершающего пробела.

Код: (Демо)

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

Для большей экономии обработки вы можете сохранить кэш переведенных значений месяца, чтобы избежать вызова двух функций (или создания экземпляра объекта datetime и вызова метода) для создания строк замены каждый раз. Однако закрытие становится немного более подробным. (Демо )

var_export(
    preg_replace_callback(
        '/^[A-Z][a-z]{2}\b/',
        function($m) {
            static $trans = [];
            $trans[$m[0]] ??= date('m', strtotime($m[0])); // only assign / call functions if needed
            return $trans[$m[0]];
        },
        $arr
    )
);

В зависимости от ваших входных строк, если буквы месяца из 3 букв гарантированно не встречаются позже в строке, вы можете создать массив перевода и вызвать strtr(), чтобы избежать регулярного выражения. (Демо )

$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";
}

Второй вариант также может использоваться для кратких названий месяцев, отличных от английского.

jspit 17.01.2023 08:33
    $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;

Другие вопросы по теме