Проблема с регулярным выражением: невозможно сопоставить шаблон переменной длины - PullRequest
2 голосов
/ 18 октября 2010

У меня проблема с регулярным выражением, использующим preg_match_all (), для сопоставления чего-либо с переменной длиной.

То, что я пытаюсь сопоставить, - это условие трафика после слова «Перегрузка». Я пришел к следующему шаблону регулярных выражений:

Congestion\s*:\s*(?P<congestion>.*)

ОднакоИзвлеките первый экземпляр до конца всего объекта, поскольку. * будет соответствовать всему.Но это не то, что я хочу, я хотел бы, чтобы это соответствовало отдельно как 3 случая.

Теперь, поскольку слова, стоящие за скоплением, могут иметь переменную длину, я не могу предсказать, сколько слов и пробелов между ними, чтобы найти более точное совпадение \ w * \ s * \ w * и т. Д.

Любые подсказки о том, как я могу продолжить отсюда?

Highway : Highway 26
Datetime : 18-Oct-2010 05:18 PM
Congestion : Traffic is slow from Smith St to Alice Springs St

Highway : Princes Highway
Datetime : 18-Oct-2010 05:18 PM
Congestion : Traffic is slow at the Flinders St / Elizabeth St intersection

Highway : Eastern Freeway
Datetime : 18-Oct-2010 05:19 PM
Congestion : Traffic is slow from Prince St to Queen St

РЕДАКТИРОВАТЬ ДЛЯ ЯРКОСТИ

Эти очень хорошо отформатированные тексты здесь, фактически полученычерез очень плохо отформатированный HTML-письмо.Здесь и там есть случайные разрывы строк, например, «Перегрузка: движение \ n медленно от Prince \ nSt до Queen St».

Поэтому при обработке электронных писем я удалил все html-коды и случайные разрывы строк и json_encode () превратил их в одну очень длинную однострочную строку без разрыва строки ...

Ответы [ 3 ]

4 голосов
/ 18 октября 2010

Обычно сопоставление регулярных выражений основано на строках.Regex предполагает, что ваша строка представляет собой одну строку.Вы можете использовать флаг «m» ( PCRE_MULTILINE ) , чтобы изменить это поведение.Затем вы можете указать PHP, что он соответствует только концу строки:

preg_match('/^Congestion\s*:\s*(?P<congestion>.*)$/m', $subject, $matches);

Обратите внимание на две вещи: во-первых, шаблон был изменен, чтобы включить в него строку-начало (^) и строку-строкуконечные ($) маркеры.Во-вторых, шаблон теперь содержит модификатор m.

2 голосов
/ 18 октября 2010

Вы можете попробовать минимальное совпадение:

Congestion\s*:\s*(?P<congestion>.*?)

Это приведет к возврату нулевых символов в названной группе «перегрузка», если только вы не можете сопоставить что-либо сразу после строки перегрузки.

Таким образом, это можно исправить, если «Шоссе» всегда запускает записи условий движения:

Congestion\s*:\s*(?P<congestion>.*?)Highway\s*:

Если это работает (я не проверял это), то сопоставляются первые записи, а последняя - нет! Это можно легко исправить, добавив текст «Highway:» в конце строки ввода.

2 голосов
/ 18 октября 2010
Congestion\s*:\s*Traffic is\s*(?P<c1>[^\n]*)\s*from\s*(?P<c2>[^\n]*)\s*to\s*(?P<c3>[^\n]*)$
...