Как описать необязательный негативный прогноз в регулярном выражении?

53
5

Мне нравится получать описание записи календарных записей, которые программа с именем hhal выдает с помощью grep. Выходной сигнал hhal выглядит так:

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. Однако, поскольку вы можете видеть, что первое назначение - повторное назначение, и там для халя добавляет эту информацию к выходу. В этом случае регулярное выражение должно гарантировать, что каждая целая часть, начинающаяся с Repeat: будет опущена, но, конечно, только в том случае, если она существует.

grep -oP "(?<=: )(.)+(?=Repeat:.+$)" получает меня Manfred treffen но не Britt Besuch

Однако grep -oP "(?<=: )(.)+(?=Repeat:.+$|$)" Дает мне описания обоих назначений, но первый со всей включенной частью "Repeat:...".

Мне кажется, что это необязательный взгляд. Я нашел аналогичный вопрос о stackoverflow, но на самом деле не понимал подход (Greedy match) и не смог его принять для моего случая.

спросил(а) 2015-05-14T12:39:00+03:00 5 лет назад
1
Решение
84

Попробуй это

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

демонстрация

ответил(а) 2015-05-14T13:57:00+03:00 5 лет назад
76

Чтобы сократить матч в Repeat: используйте этот lookbehind:

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

Вместо того, чтобы сопоставлять все, начиная с Repeat: до конца, сопоставляйте только Repeat: с пробелом перед ним. Другими словами, удалите .+$ Из вашего lookbehind. Этого достаточно, чтобы остановить совпадение после имени, давая результат, который вы ожидаете.

т.е.

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

Demo.

ответил(а) 2015-05-14T12:47:00+03:00 5 лет назад
38

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

Вы можете попробовать это. Смотрите демоверсию.

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

ответил(а) 2015-05-14T12:51:00+03:00 5 лет назад
39

Вам не нужно добавлять repeat в ваше регулярное выражение, все, что вам нужно, это группа захвата после даты :

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

DEMO

Но если вы просто хотите использовать : и вы просто хотите, чтобы имена и имена были 2 частью, вы можете использовать следующее регулярное выражение:

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

Если вы не знаете длину имени после : вы можете использовать следующее регулярное выражение:

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

демонстрация

ответил(а) 2015-05-14T12:47:00+03:00 5 лет назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема