如何在正则表达式中描述一个可选的负前瞻?

How to describe an optional negative lookahead in regular expression?

我想通过使用 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: .+$|$)" 给了我两个约会的描述,但第一个包含整个 "Repeat:…" 部分。

我似乎需要的是一个可选的先行。我在 Whosebug 上发现了一个类似的问题,但并没有真正理解这种方法(贪婪匹配),也无法为我的案例采用它。

要在 Repeat: 处切断比赛,请使用此回顾:

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

与其匹配从 Repeat: 开始到结尾的所有内容,不如只匹配 Repeat:,前面有一个 space。换句话说,从你的回顾中删除 .+$ 。这足以在名称后停止匹配,产生您期望的结果。

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

Demo.

您不需要在您的正则表达式中添加 repeat,您只需要在 :

的日期之后添加一个捕获组
\d+\.\d+\.\d+:\s?(\w+ \w+)

DEMO

但是如果你只想使用 : 并且你只想要名称并且名称是 2 部分你可以使用以下正则表达式:

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

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

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

Demo

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

您可以尝试 this.See 演示。

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

试试这个

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

Demo