Почему в моем pcregrep Regex не работает позитивный взгляд? - PullRequest
1 голос
/ 31 мая 2019

Я написал Regex, используя pcregrep, и все вело себя так, как ожидалось, пока я не добавил положительный прогноз.

Сценарий:

У меня есть следующий текстовый файл:

a
b
c
a
c

Цель:

Я хочу использовать Regex с pcregrep, чтобы вернуть строку, содержащую a, и строку, содержащую c, и строку, содержащую b, между которыми не перехвачено. Таким образом, он будет захватывать первые три строки (a, b, c) и возвращать первую (a) и третью (c) строку. не захватывает четвертую и пятую строки, потому что между ними нет строки b. Таким образом, результат будет:

a
c

Что я пробовал

Если я запускаю pcregrep -M 'a\nb\nc\n' ( команда 1 ), это захватывает и возвращает:

a
b
c

как и ожидалось. Итак, теперь я хочу изменить это, чтобы захватить строку b с положительным прогнозом. Я попробовал это: pcregrep -M 'a\n(?=(b\n))c\n' ( команда 2 ). Однако это ничего не возвращает.

Мой вопрос:

Почему команда 2 не возвращает ожидаемый результат, тогда как команда 1 делает? Как я могу вернуть желаемый результат? Я знаю, что есть и другие способы, кроме pcregrep, но учтите, что я хочу использовать pcregrep, потому что буду расширять функциональность для решения подобных проблем.

Спасибо!

Ответы [ 2 ]

2 голосов
/ 31 мая 2019

Вы можете использовать 2 группы захвата с опцией -o:

pcregrep -M -o1 -o2 '(a\n)b\n(c)\n' file

a
c

Подробности:

  • (...): в регулярных выражениях он используется для захвата групп
  • -o1 -o2: печатает только группы захвата # 1 и # 2

Обратите внимание, что ваше регулярное выражение a\n(?=(b\n))c\nне сработает, потому что предвидение - это просто утверждение с соответствием нулевой ширины.Ваше регулярное выражение утверждает наличие b\n после a\n, что вполне нормально, но оно пытается сопоставить c\n сразу после a\n, и в этом случае сопоставление не удается.

1 голос
/ 31 мая 2019

Почему команда 2 не возвращает ожидаемый результат, а команда 1?Поскольку команда 2 - это другое выражение,

(?=…) - это точка зрения с нулевой шириной

, которую вы указали: Я хочу a, за которым следует перевод строки, за которым следует b с последующим переводом строки.В этой позиции я также хочу, чтобы c сопровождался переводом строки.

PS, чтобы просто получить a и c, может быть, это поможет?

pcregrep -M 'a\nb\nc\n' | pcregrep -M 'a|c'

...