Перемещение частей {token} в конец строки в зависимости от условия

Из многострочного ввода я хочу переместить токены, если они находятся внутри {} и соответствуют некоторому числу. Пример ввода

# (811) (1485) [2756] {29} [555] {15} 
# (811) (1476) {20} {15} (1485) [196] [2441] 
# (911) (619) {19} (1476) [2765] [2752] {21}

Из приведенной выше строки я хочу переместить токены, если это не {19} или {20}, в конец строки.
Пример вывода

# (811) (1485) [2756] [555] {15} {29} 
# (811) (1476) {20} (1485) [196] [2441] {15} 
# (911) (619) {19} (1476) [2765] [2752] {21}

Я могу провести предварительный матч с preg_match_all("/\{\d+\}/", $input, $matches);, но что тогда делать?

Стоит ли изучать 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
0
36
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы можете собрать все совпадения для {19} и {20} для каждой строки в массиве, отфильтровав разделенную строку, а затем снова соединив их вместе.

Пример кода

foreach (explode("\n", $str) as $str) {
    $result = array_reduce(explode(" ", $str), function($acc, $curr) {
        preg_match("/{(?!19|20)\d+}/", $curr) ? $acc['move'][] = $curr :  $acc['valid'][] = $curr;
        return $acc;
    }, ['valid' => [], 'move' => []]);
    echo implode(" ", array_merge($result['valid'], array_reverse($result['move']))) . PHP_EOL;
}

Выход

# (811) (1485) [2756] [555] {15} {29}
# (811) (1476) {20} (1485) [196] [2441] {15}
# (911) (619) {19} (1476) [2765] [2752] {21}

О коде

Код сначала разбивает строку на символы новой строки, потому что движущиеся части находятся в каждой строке.

Затем вы можете использовать, например, разнесение, чтобы разделить строку на пробел, и использовать array_reduce для проверки отдельных частей.

Вы можете инициализировать уменьшение массива с помощью массива, содержащего 2 массива ['valid' => [], 'move' => []]

В функции обратного вызова аккумулятор $acc уже содержит этот массив, который вы затем можете заполнить разницей в совпадениях, используя ключ массива, например $acc['valid']

Шаблон {(?!19|20)\d+} соответствует {, а затем утверждает, что за ним непосредственно не следует ни 19}, ни 20}. Если это так, то он соответствует 1 или более цифрам между фигурными скобками.

Чтобы получить результат с одним пробелом между «словами», вы можете объединить оба массива, а затем использовать implode для пробела.

См. демонстрация php.

Пожалуйста объясните код

www.friend0.in 03.04.2022 19:42

@www.friend0.in Я добавил объяснение кода.

The fourth bird 03.04.2022 19:54

Это решение позволяет использовать несколько знаков препинания. В этом примере все токены, начинающиеся с '{' или '(', будут перемещены в конец:

$input = <<< STRING
# (811) (1485) [2756] {29} [555] {15}
# (811) (1476) {20} {15} (1485) [196] [2441]
# (911) (619) {19} (1476) [2765] [2752] {21}
STRING;

$excluded = [ '{19}', '{20}', '(811)' ];

$startPunctuations = array_unique(array_map(fn($exclude) => $exclude[0], $excluded));

$result = implode(
  "\n",
  array_map(
    fn($line): string => implode(
      ' ',
      array_map(
        fn($element) => implode(' ', $element),
        array_reduce(
          explode(' ', $line),
          fn($carry, $item) => in_array($item[0], $startPunctuations) && !in_array($item, $excluded)
            ? [ $carry[0], [ ...$carry[1], $item ] ]
            : [ [ ...$carry[0], $item ], $carry[1] ],
          [ [], [] ]
        )
      )
    ),
    explode("\n", $input)
  )
);

echo $result;

// # (811) [2756] [555] (1485) {29} {15}
// # (811) {20} [196] [2441] (1476) {15} (1485)
// # {19} [2765] [2752] (911) (619) (1476) {21}

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