2014-02-10 3 views
1

Я пытаюсь сопоставить несколько строк документа с использованием регулярного выражения в PHP. Я знаю параметр \ s, но каким-то образом я не могу определить правильное регулярное выражение (используя онлайн-инструменты для тестирования регулярных выражений).PHP Match Multipline Line с Regex

Файл является ческим файлом и выглядит следующим образом:

BEGIN:VEVENT 
LAST-MODIFIED:20140203T092537Z 
CREATED:20140101T161157Z 
DTSTART:20140220T150000Z 
DTSTAMP:20140203T092537Z 
DTEND:20140220T170000Z 
SUMMARY:Summary of Event 
UID:appointment_27140 
END:VEVENT 
BEGIN:VEVENT 
LAST-MODIFIED:20140203T092537Z 
CREATED:20140101T161157Z 
DTSTART:20140221T070000Z 
DTSTAMP:20140203T092537Z 
DTEND:20140221T130000Z 
SUMMARY:Event 2 
UID:appointment_27135 
LOCATION:TINF11B2 
END:VEVENT 

Я хотел бы, чтобы соответствовать целому событию (от НАЧАТЬ: EVENT до конца: EVENT), если он содержит определенные ключевые слова в кратком изложении событий.

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

/BEGIN:VEVENT(.*)Event 2(.*)END:VEVENT/s

+0

Почему бы не работать с анализатором ческих или класса таким образом, что вы можете работать с полем интересующих вас непосредственно? –

+0

Это всего лишь небольшой скрипт php, который исправляет ошибку в календаре моих университетов. С помощью этого расширения он также должен иметь возможность фильтровать определенные лекции. Это действительно просто удаление нескольких событий в оригинальной iCal. Я не думаю, что есть необходимость использовать iCal Parser, поскольку я действительно не пытаюсь получить информацию из iCal/modfiy iCal сильно –

ответ

3
(BEGIN:VEVENT(?:(?!BEGIN:VEVENT).)*Event 2.*?END:VEVENT) 
  1. Захвата всего текст события
  2. Match строка «BEGIN: VEVENT»,
  3. Ешь и не захватить ноль или более символов, которые не упреждающие «BEGIN: VEVENT»,
  4. матч строка "Событие 2",
  5. Ешь ноль или более символов не жадный,
  6. Match строка "END: VEVENT"

Regex Demo:http://regex101.com/r/aK6lR4

PHP код:

//$events contains the file text 
$search = 'Event 2'; 
$matches = array(); 
$found = preg_match('/BEGIN:VEVENT(?:(?!BEGIN:VEVENT).)*' . $search . '.*?END:VEVENT/s', $events, $matches); 
if ($found === 1) { 
    echo $matches[0]; 
} 

В качестве альтернативы вы можете использовать preg_match_all, чтобы соответствовать более чем одно событие. $ matches [0] будет массивом вместо строки, а $ found будет содержать количество совпадений.

+0

Это должно работать, я считаю, +1 – anubhava

0

Я нашел аналогичный вопрос на StackOverflow: RegEx: can't figure out the expression to match lines with individual events and match only those containing certain word

Вот ссылка к онлайн-демонстрации: http://regex101.com/r/uX3gV6

+0

Правда, но есть [лучший ответ прямо здесь] (http: // stackoverflow .com/а/21681729/20938). В частности, вы можете использовать '.' вместо' [\ s \ S] ', и он должен идти после просмотра, а не раньше. –

1

Способ сделать это:

$kw = 'Event 2'; 

$pattern = sprintf('~BEGIN:([^\r\n]+)\R((?>[^E%s]++|\B[E%s]|(?!END:\1)%s(?!%s)|(?!%s)E(?!ND:\1))+)%s(?2)END:\1~', 
        $kw[0], $kw[0], $kw[0], substr($kw,1), $kw, $kw); 

preg_match_all($pattern, $iCalContent, $matches); 

print_r($matches[0]);