Regex с несколькими группами захвата

1

У меня есть рабочее регулярное выражение для извлечения нескольких данных. Код php выглядит следующим образом:

<?php

$re = "/(\\d{2}.\\d{2}.\\d{2}).+(\\w{3}).+\\w{3}.+(\\w{2}\\s\\d{4}).+(\\d{2}:\\d{2}\\n).+(\\d{2}.\\d{2}.\\d{2}).+(\\w{2}\\s\\d{4}).+(\\d{2}:\\d{2}\\n).+((FNC|PXO)\\d{3})/"; 
$str = "***NEUBUCHUNG ***\n 24.01.15  TXL  FNC  AB 2306  11:40   15:20\n 31.01.15  FNC  TXL  AB 2307  16:05\n FNC044  RESIDENCIAL VILA LUSITANI    9000-120 FUNCHAL\n  1  DOPPELZIMMER                     FRUEHSTUECK\n SPO1101\n INKL. REISELEITUNG UND TRANSFER AB/BIS\n FLUGHAFEN\n F368966  HERR EIDAM, KLAUS               54\n F368966  FRAU EIDAM, SONJA               54"; 

$str2 = "***ÄNDERUNG ***\nNEU:11.04.15 DUS  AB 2646  13:15   16:25\n    18.04.15 FNC  DUS  AB 2647  17:15\n   FNC027    PESTANA CARLTON MADEIRA   9004-531 FUNCHAL\n 1  DO-MEERBLICK                       F\nF365474 HERR   PETERS, HANS                                O 03.01.15\nLANGZEITERMÄSSIGUNG 10%\nSPO-JAN_SALES 20%\nFRÜHBUCHER 10%\nINKL. REISELEITUNG UND TRANSFER AB/BIS\nFLUGHAFEN\nZimmer in ruhiger Lage\n(unverbindlicher Kundenwunsch)\nNEU:\nF365474 FRAU   PETERS, ULRIKE                              O 03.01.15"; 

preg_match($re, $str, $matches);
print_r($matches)
?>

https://ideone.com/UdIaA7

Regex with str: https://regex101.com/r/rF0uP7/5

Регулярное выражение с str2: https://regex101.com/r/cV6iF9/1

Однако он отлично работает для str, который не совпадает с str2, и я не могу найти причину

Теги:
preg-match
preg-match-all
expression

2 ответа

1
Лучший ответ

Параметр .+(\w{3}) в начале должен быть необязательным. Оберните его (?:.+(\w{3}))? ,

См. Демо-версию regex

Кроме того, у вас слишком много .+, В большинстве мест, вы должны просто сопоставлять пробелы и, таким образом, лучше превращаться в \s+. Кроме того, точки, предназначенные для соответствия буквальным точкам, должны быть экранированы.

Используйте более оптимизированный:

(\d{2}\.\d{2}\.\d{2})(?:\s+(\w{3}))?\s+\w{3}\s+(\w{2}\s\d{4}).+(\d{2}:\d{2}\n)\s+(\d{2}\.\d{2}\.\d{2}).+(\w{2}\s\d{4})\s+(\d{2}:\d{2}\n).+((FNC|PXO)\d{3})

См. Эту демонстрацию regex

  • 1
    Обратите внимание, что вы не должны использовать какие-либо модификаторы с шаблоном регулярных выражений в PHP (возможно, /u если вы имеете дело с UTF-текстами). Просто preg_match_all('~(\d{2}\.\d{2}\.\d{2})(?:\s+(\w{3}))?\s+\w{3}\s+(\w{2}\s\d{4}).+(\d{2}:\d{2}\n)\s+(\d{2}\.\d{2}\.\d{2}).+(\w{2}\s\d{4})\s+(\d{2}:\d{2}\n).+((FNC|PXO)\d{3})~u', $str, $matches) .
  • 0
    Вы мастер Виктор! Спасибо :)
2

Однако он отлично работает для str, который не совпадает с str2, и я не могу найти причину

Вот выражение Culprit: (\\w{3}).+\\w{3}

И в $ str у вас было 24.01.15 TXL FNC AB

Но в $ str2 у вас было: 11.04.15 DUS AB

Ваше Regex могло бы выглядеть так:

$re = "#(\d{2}\.\d{2}\.\d{2})(?:\s+(\w{3}))?\s+\w{3}\s+(\w{2}\s\d{4}).+(\d{2}:\d{2}\n)\s+(\d{2}\.\d{2}\.\d{2}).+(\w{2}\s\d{4})\s+(\d{2}:\d{2}\n).+((FNC|PXO)\d{3})#si"; 

Быстрый тест.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню