我正在尝试使用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
答案 0 :(得分:3)
(BEGIN:VEVENT(?:(?!BEGIN:VEVENT).)*Event 2.*?END:VEVENT)
正则表达式演示: 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)
我在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