2015-05-14 39 views
1

我喜欢通过使用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 treffenBritt Besuch的例子。但是,正如您所看到的,第一个约会是重复约会,而khal则将这些信息添加到输出中。在这种情况下,正则表达式必须确保从Repeat:开始的每个整个部分都将被省略,但当然只有当它存在时才会被忽略。

grep -oP "(?<=:)(.)+(?=Repeat: .+$)"让我 Manfred treffen但不Britt Besuch

然而grep -oP "(?<=:)(.)+(?=Repeat: .+$|$)"给了我两个约会,但第一个与整个的说明“重复:” ......包括一部分。

我似乎需要的是一个可选的lookahead。我在stackoverflow上发现了一个类似的问题,但并没有真正理解这个方法(贪婪的匹配),也不可能为我的情况采用它。

回答

0

试试这个

(?<=\d{4}:).+?(?=Repeat|$) 

Demo

3

要剪切的比赛在Repeat:使用此回顾后:

(?<=:)(.+)(?= Repeat:|$) 

而不是一切都开始Repeat:到最后,比赛只Repeat:匹配,与在它前面的空间。换句话说,从你的后方移除.+$。这足以阻止名称之后的匹配,产生您期望的结果。

grep -oP '(?<=:).+(?= Repeat:|$)' file 

Demo.

+0

你并不需要去捕获组。 –

+0

这将匹配'Britt Besuch这是'09.05内的一个句子'。 - 12.05.2015:布里特Besuch这是一个句子' – Kasramvd

+0

奇怪,在演示它的作品。在我的计算机上,但是我仍然得到所有“重复:”信息字符串,直到结尾 –

0

你并不需要与:

\d+\.\d+\.\d+:\s?(\w+ \w+) 

DEMO添加repeat在你的正则表达式所有你需要的是一个捕获组日期之后

但如果你只是想用:只想和你的姓名和名称是2部分,你可以使用下面的正则表达式:

(?<=:)[a-zA-Z]+ [a-zA-Z]+ 

如果你不知道:后名称的长度,你可以使用下面的正则表达式:

\d+\.\d+\.\d+:\s?(.+)((?= \w+:)|$) 

Demo

+0

好吧,这个例子适用。我应该补充说,任命说明的长度和原因可能会有所不同。对不起 –

+0

@CutúChiqueño是的,结账编辑! – Kasramvd

0
(?m)(?<=(?<!Repeat):).*?(?=Repeat|$) 

你可以试试this.See演示。

https://regex101.com/r/mT0iE7/19

+0

这个正则表达式根本不给我任何结果,虽然我明白从第一个“:” –

+0

@CutúChiqueño的外观中排除“重复”的想法,您正在使用它与'grep -P'对吗?它会是'grep - P“(?m)(?<=(?<!Repeat):)。*?(?=重复| $)”' – vks