我想通过使用grep来获得一个名为khal的程序输出的日历条目的约会描述。 khal的输出如下:
20:30-22:30 13.05.2015: Manfred treffen Repeat: FREQ=WEEKLY;BYDAY=WE;WKST=MO
09.05. - 12.05.2015: Britt Besuch
在示例中,我想匹配Manfred treffen
和Britt Besuch
。但是,正如您所看到的那样,第一个约会是重复约会,并且khal会将这些信息添加到输出中。在这种情况下,正则表达式必须确保将省略以Repeat:
开头的每个部分,但当然只有它存在。
grep -oP "(?<=: )(.)+(?=Repeat: .+$)"
得到了我
Manfred treffen
但不是Britt Besuch
然而grep -oP "(?<=: )(.)+(?=Repeat: .+$|$)"
给了我两个约会的描述,但第一个约会与整个&#34;重复:...&#34;部分包括。
我似乎需要一个可选的前瞻。我在stackoverflow上发现了一个类似的问题但是并没有真正理解这种方法(贪婪匹配),也没有可能在我的情况下采用它。
答案 0 :(得分:3)
要在Repeat:
切断匹配,请使用此lookbehind:
(?<=: )(.+)(?= Repeat:|$)
不是将从Repeat:
开始的所有内容都匹配到结尾,而只匹配Repeat:
,前面有一个空格。换句话说,从您的lookbehind中删除.+$
。这足以在名称后停止匹配,产生您期望的结果。
即
grep -oP '(?<=: ).+(?= Repeat:|$)' file
答案 1 :(得分:0)
您不需要在正则表达式中添加repeat
,只需在:
\d+\.\d+\.\d+:\s?(\w+ \w+)
但是如果您只想使用:
并且您只想要名称和名称是2部分,则可以使用以下正则表达式:
(?<=: )[a-zA-Z]+ [a-zA-Z]+
如果您不知道:
之后的姓名长度,可以使用以下正则表达式:
\d+\.\d+\.\d+:\s?(.+)((?= \w+:)|$)
答案 2 :(得分:0)
答案 3 :(得分:0)