PHP与正则表达式匹配多行

时间:2014-02-10 14:27:13

标签: php regex

我正在尝试使用PHP中的正则表达式匹配文档的多行。我知道\ s选项,但不知怎的,我无法弄清楚正确的正则表达式(使用在线正则表达式测试工具)。

该文件是iCal文件,如下所示:

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

如果事件摘要中包含某些关键字,我想匹配整个事件(从BEGIN:EVENT到END:EVENT)。

我认为匹配上述iCal中第二个事件的正则表达式看起来与此类似:

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

3 个答案:

答案 0 :(得分:3)

(BEGIN:VEVENT(?:(?!BEGIN:VEVENT).)*Event 2.*?END:VEVENT)
  1. 捕获整个事件文本
  2. 匹配字符串“BEGIN:VEVENT”,
  3. 吃掉并且不捕获零个或多个没有前瞻的字符“开始:VEVENT”,
  4. 匹配字符串“Event 2”,
  5. 吃掉零个或多个不贪婪的字符,
  6. 匹配字符串“END:VEVENT”
  7. 正则表达式演示: 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将包含匹配数。

答案 1 :(得分: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]);

答案 2 :(得分:0)