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

#php #regex #pattern-matching

#php #регулярное выражение #сопоставление шаблонов

Вопрос:

У меня есть строка, подобная этой:

Заказ билетов: № 123123123. CED-MSW-RPG-MOW-CEK PODYLOVA /ALEMR 555 423578932 19OCT11 Заказ билетов: № 123123123. 346257. CSK-MOW-PRG-MOW-CWQ PODYLOVA/ALEMR 555 45837043 19OCT11

Мне нужно собрать все коды, которые являются CEK, MOW, PRG и так далее. Сначала я попробовал этот шаблон:

 $pattern = '#[-|s]([A-Z]{3})#';
  

В результате я получаю все мои коды (все в порядке) и первые 3 символа фамилии пользователя: «POD» от «PODYLOVA». Если я скажу «после моего кода должен быть символ дефиса или свободного места, изменив мой шаблон на этот:

 $pattern = '#[-|s]([A-Z]{3})[-|s]#';
  

Мой $matches var имеет это:

 array (
  0 => 
  array (
    0 => ' CED-',
    1 => '-RPG-',
    2 => '-CEK ',
    3 => ' CSK-',
    4 => '-PRG-',
    5 => '-CWQ ',
  ),
  1 => 
  array (
    0 => 'CED',
    1 => 'RPG',
    2 => 'CEK',
    3 => 'CSK',
    4 => 'PRG',
    5 => 'CWQ',
  ),
)
  

Вы можете видеть, что мой шаблон не «разделяет» дефис между желаемыми кодами.

Я вижу два решения, но не могу представить шаблон, который подойдет:

  1. Создайте шаблон для разделения дефиса между кодами
  2. Создайте более сложный шаблон: сначала соберите текст, содержащий коды («CED-MSW-RPG-MOW-CEK»), а затем получите все #([A-Z] {3}# внутри этого шаблона.

Кажется, что решение № 1 является лучшим в моем случае, но как оно должно выглядеть?

Ответ №1:

Попробуйте это:

b([A-Z]{3})b

HTH

Комментарии:

1. Вам даже больше не нужны круглые скобки. И вы можете дать подсказку @the_ghost, которая b является границей слова .

2. Спасибо вам! Я просто ходил по этому шаблону и даже пробовал b, но не думал, что все так просто

Ответ №2:

дает ли это вам то, что вы хотите?

 (?<=-|s)[A-Z]{3}(?=-|s)
  

проверено с помощью grep:

 kent$  echo "Tickets order: № 123123123. CED-MSW-RPG-MOW-CEK PODYLOVA/ALEMR 555 423578932 19OCT11 Tickets order: № 123123123. 346257. CSK-MOW-PRG-MOW-CWQ PODYLOVA/ALEMR 555 45837043 19OCT11"|grep -Po '(?<=-|s)[A-Z]{3}(?=-|s)' 
CED
MSW
RPG
MOW
CEK
CSK
MOW
PRG
MOW
CWQ
  

Комментарии:

1. Использует ли ваш вариант вложенные группы, как я просил?