Perl在`-0`模式下匹配换行符

时间:2012-02-05 06:41:33

标签: regex perl newline

问题

假设我有这样的文件:

I've got a loverly bunch of coconut trees.

Newlines!

Bahahaha
Newlines!
the end.

我想替换“Newlines”的出现!那个被空白线包围着(比如说)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!”。

现在我尝试只选择“Newlines!”被\ n:

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

没有运气(请注意 - 我不需要s开关,因为我没有使用.而且我不需要m开关,因为我没有使用^$;无论如何,添加它们都无法实现这一点。 Lookaheads / behinds也不起作用:

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用空字符替换换行符。

所以我的问题是 - 如何匹配这种模式(我不想在正则表达式的@pattern @ replacement @ flags'结构之外写任何perl?)

是否可以匹配此空字符?我试过了:

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

无效。

有谁能告诉我如何在perl中匹配换行符?是否在-0模式下?或者我应该使用awk之类的东西? (我从sed开始,但即使使用-r,它似乎也没有前瞻/支持。我去了perl,因为我对awk并不熟悉。)

欢呼声。

(PS:this question不是我想要的,因为他们的问题与.+匹配换行符有关。)

3 个答案:

答案 0 :(得分:2)

以下应该适合你:

perl -0pe 's@(?<=\n\n)Newlines!(?=\n\n)@NEWLINES!@g'

答案 1 :(得分:1)

如果文件小到足以一下子插入内存:

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 }'

答案 2 :(得分:1)

我认为你采取行动的方式导致你以一种无效的方式组合可能的解决方案。

如果你使用内联编辑标志,你可以这样做:

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

我已经加倍了\ n以确保你只获得上面和下面有空行的那些。