perl: требуется регулярное выражение для замены текста в двух словах с определенными условиями - PullRequest
2 голосов
/ 24 апреля 2019

Этот вопрос, похоже, такой же, как и Отрицательный прогноз с awk или sed невозможен, но только perl поддерживает Но это не то же самое.

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

У меня есть следующий текст (sample.txt)

Условие 1: содержит PQXY между QWWK и KWWQ, поэтому не требуется

QWWK erly jointure  PQXY In said devonshire 
Drift allow green son walls years for blush.
acceptance son KWWQ

Условие 2: QWWK не запускается в начале строки, поэтому не требуется

other QWWK get him his projection ar saw fat sudden edward
sociable felicity supplied mr. September
ay now many. Alte KWWQ

Условие 3: KWWQ находится не в конце строки, поэтому не требуется

QWWK ble formerly six but hand
r way now many. Alteration you 
occasion ham for  KWWQ other

Условие 4: QWWK начинается при запуске, а KWWQ заканчивается в конце, и PQXY отсутствует, поэтому это то, что нужно

QWWK n zealously arranging fr
eal park so rest we on. Ignorant d
he possession insensible sympathi KWWQ
.......

Пожалуйста, обратите внимание на слова QWWK PQXY и KWWQ

Мой текст состоит из нескольких строк.

I want to match text between QWWK and KWWQ

Condition 1: should not contain the word PQXY inbetween

Condition 2: QWWK should start at the beginning of the line

Condition 3: KWWQ should be at the end of the line

В возвышенном тексте я соответствую, используя:

(?s)(^QWWK(?:(?!QWWK).)*?KWWQ\n) 

и соответствует условию 4

QWWK n zealously arranging fr

eal park so rest we on. Ignorant d

 he possession insensible sympathi KWWQ

Таким образом, оно не соответствует условию 1, условию 2 и условию 3.

Я пытаюсь с помощью perl заменить условие 4 некоторым текстом, который я пытаюсь

$ perl -0777pe 's/^QWWK(?!QWWK).*?KWWQ\n/sometext/gs' sample.txt > sample_mod.txt 

Но sample_mod.txt не заменил кодировку 4

я тоже пробовал

$ perl -0777pe 's/\nQWWK(?!QWWK).*?KWWQ\n/sometext/gs' sample.txt > sample_mod.txt 

Удаляет как условие 1, так и условие4

Ответы [ 3 ]

1 голос
/ 24 апреля 2019

/m изменяет определение ^ и $ на начало и конец строки соответственно.

То, что вы просили:

/^QWWK(?:(?!PQXY).)*KWWQ$/msg

Что вы, вероятно, хотите:

/^QWWK(?:(?!QWWK|PQXY|KWWQ).)*KWWQ$/msg

Оптимизировано: (Уменьшает количество выполненных поисков)

/
   ^ QWWK
   [^KPQ]*+
   (?: (?: K (?!WWQ)
       |   P (?!QXY)
       |   Q (?!WWK)
       )
       [^KPQ]*+
   )*+
   KWWQ $
/xmg
1 голос
/ 24 апреля 2019

Методом проб и ошибок я придумал следующее регулярное выражение:

/^QWWK(?!.*PQXY)(?!.*KWWQ[^\n])(.*?)KWWQ$/gms

Модификатор /m означает, что вход является многострочным, а ^ соответствует началу any строка и $ соответствует концу любая строка

С модификатором /s метасимвол . означает любой символ , включая символы новой строки

/^QWWK .../m

Найти подстроку, которая начинается с QWWK в начале строки

/... KWWQ$/m

и заканчивается KWWQ в конце строки

/^QWWK(?!.*PQXY)/s

Сопоставление не выполняется, если за QWWK следует любое количество символов (включая новые строки) и текст PQXY.

/^QWWK ... (?!.KWWQ[^\n]) ... /s

Сопоставление также не выполняется, если после QWWK следует любоеколичество символов, текст KWWQ и любой символ, который не является новой строкой.

/^QWWK(.*?)KWWQ$/s

Поместите любой текст между QWWK и KWWQ, включая новые строки, в группу захвата.Используйте не жадный модификатор ?, чтобы регулярное выражение не пыталось перехватить данные от раннего QWWK наблюдения до самого последнего возможного KWWQ наблюдения.

0 голосов
/ 24 апреля 2019

Я прочитал этот пост Многострочный поиск заменить на Perl

Я попробовал следующее и, похоже, работает:

$ perl -0pe 's/^QWWK(?:(?!PQXY).)*?KWWQ\n/sometext/gms' sample.txt > sample_mod.txt 

Тогда заменяется только условие 4, а остальные остаются нетронутыми

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...