正则表达式:无法找出将行与单个事件匹配的表达式,而只能匹配包含特定单词的行



我正在尝试清理和合并一些较旧的日历文件(x.ics),使用Sublime Text作为编辑器。打开文件会得到一个长文件,如下所示。我想删除(即不替换)摘要中提及生日的文件中的所有条目 (VEVENT) 并保留所有其他条目,所以我使用正则表达式作为一种方法。

我设法匹配了从 BEGIN:VEVENT 到 END:VEVENT 的行,但是我无法设置一个表达式来仅过滤包含生日的匹配项/VEVENT。

我现在拥有的是这个表达:BEGIN:VEVENT(.|n)*?(Birthday)(.|n)*?END:VEVENTn。显然,这不是正确的表达式,因为它在找到生日后从 BEGIN 匹配到 END 匹配,并且与单个 VEVENT 不匹配。

任何人都可以帮我找到解决方案吗?将不胜感激!

BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:2009
X-WR-TIMEZONE:Europe/Amsterdam
X-WR-CALDESC:
BEGIN:VEVENT
DTSTART:20110606T170500Z
DTEND:20110614T121000Z
DTSTAMP:20140108T203731Z
UID:CSVConvert0127bd7e37d8feb5e1daaa909729c2ba
CREATED:19000101T120000Z
DESCRIPTION:
LAST-MODIFIED:19700101T000000Z
LOCATION:Amsterdam
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Study
TRANSP:OPAQUE
END:VEVENT
.
.
.
BEGIN:VEVENT
DTSTART;VALUE=DATE:20110704
DTEND;VALUE=DATE:20110705
DTSTAMP:20140108T203731Z
UID:CSVConvert02f7a0b537b60e5601035a356dfd6a06
CREATED:19000101T120000Z
DESCRIPTION:
LAST-MODIFIED:19700101T000000Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Mark's Birthday
TRANSP:TRANSPARENT
END:VEVENT
END:VCALENDAR

我认为您需要添加一个前瞻以防止它超出边界:

BEGIN:VEVENT([sS](?!BEGIN:VEVENT))+?Birthday[sS]+?END:VEVENT

注意:我不是ST用户,不知道它是否支持。

首先:如果我这样做,特别是如果它开始变得更加复杂,我会快速编写一个Perl/Python/etc脚本来过滤内容。 这将更加强大和灵活,并且不那么挑剔。 正则表达式并不擅长这种事情。

也就是说,你可以单独使用正则表达式来完成这项工作,尽管它很混乱。 您需要做的是防止 END 行包含在您的"中间部分"中。 为此,如果Sublime不支持前瞻,您可以这样做:

BEGIN:VEVENTn(([^E]|E[^N]|EN[^D]).*n)*(([^E]|E[^N]|EN[^D]).*Birthday.*n)(([^E]|E[^N]|EN[^D]).*n)*END:VEVENTn

扩展了一点:

BEGIN:VEVENTn
(([^E]|E[^N]|EN[^D]).*n)*           //Any number of non-END lines
(([^E]|E[^N]|EN[^D]).*Birthday.*n)  //At least one Birthday line
(([^E]|E[^N]|EN[^D]).*n)*           //More non-END lines
END:VEVENTn

从技术上讲,您还可以排除生日行上的 END 位,因为 END:VEVENT 无论如何都不会包含"生日"。

同样,这非常混乱,如果事情变得更加复杂,我会推荐上面的前瞻解决方案或自定义脚本。 但是我解决了这个问题,所以我想无论如何我都会发布它。 也许把它展示给你的孩子,给他们一个很好的吓唬什么的。

最新更新