Perl соответствует новой строке в режиме `-0` - PullRequest
1 голос
/ 05 февраля 2012

Вопрос

Предположим, у меня есть файл, подобный этому:

I've got a loverly bunch of coconut trees.

Newlines!

Bahahaha
Newlines!
the end.

Я хотел бы заменить вхождение "Новые строки!"который окружен пустыми строками с (скажем) NEWLINES !.Итак, идеальный вывод:

I've got a loverly bunch of coconut trees.

NEWLINES!

Bahahaha
Newlines!
the end.

Попытки

Игнорируя «в окружении строк», я могу сделать:

perl -p -e 's@Newlines!@NEWLINES!@g' input.txt

Что заменяет все вхождения «строк»!"с "NEWLINES!".

Теперь я пытаюсь выделить только "Newlines!"окруженный \ n:

perl -p -e 's@\nNewlines!\n@\nNEWLINES!\n@g' input.txt

Не повезло (обратите внимание - мне не нужен переключатель s, потому что я не использую ., и мне не нужен переключатель m, потому чтоЯ не использую ^ и $; независимо от того, добавление их не делает эту работу).Задние / задние части также не работают:

perl -p -e 's@(?<=\n)Newlines!(?=\n)@NEWLINES!@g' input.txt

После небольшого поиска я вижу, что perl читает в файле построчно (имеет смысл; sed тоже делает).Итак, я использую переключатель -0:

perl -0p -e 's@(?<=\n)Newlines!(?=\n)@NEWLINES!@g' input.txt

Конечно, это не работает - -0 заменяет символы новой строки на нулевой символ.

Так что мой вопрос- Как я могу сопоставить этот шаблон (я бы предпочел не писать никакого perl, кроме конструкции регулярного выражения @ pattern @ replace @ flags ')?

Возможно ли сопоставить этот нулевой символ?Я попытался:

perl -0p -e 's@(?<=\0)Newlines!(?=\0)@NEWLINES!@g' input.txt

безрезультатно.

Может кто-нибудь сказать мне, как сопоставить переводы строк в Perl?В режиме -0 или нет?Или я должен использовать что-то вроде awk?(Я начал с sed, но, похоже, у него нет поддержки «назад / позади» даже с -r. Я пошел на Perl, потому что я совсем не знаком с awk).

ура.

(PS: этот вопрос не тот вопрос, который мне нужен, потому что их проблема была связана с .+ совпадающим переводом строки).

Ответы [ 3 ]

2 голосов
/ 05 февраля 2012

Следующие должны работать для вас:

perl -0pe 's@(?<=\n\n)Newlines!(?=\n\n)@NEWLINES!@g'
1 голос
/ 05 февраля 2012

Я думаю, что то, как вы поступили, заставило вас объединить возможные решения таким образом, чтобы это не сработало.

если вы используете встроенный флаг редактирования, вы можете сделать это следующим образом:

perl -0p -i.bk -e 's/\n\nNewlines!\n\n/\n\nNEWLINES!\n\n/g' input.txt

Я удвоил \ n, чтобы убедиться, что вы получаете только те, у которых пустые строки выше и ниже.

1 голос
/ 05 февраля 2012

Если файл достаточно мал, чтобы его можно было залить в память сразу:

perl -0777 -pe 's/\n\nNewlines!(?=\n\n)/\n\nNEWLINES!/g'

В противном случае сохраните буфер трех последних строк следующим образом:

perl -ne 'push @buffer, $_; $buffer[1] = "NEWLINES!\n" if @buffer == 3 && ' \
      -e 'join("", @buffer) eq "\nNewlines!\n\n"; ' \
      -e 'print shift @buffer if @buffer == 3; END { print @buffer }'
...