Perl 在“-0”模式下匹配换行符
问题
假设我有一个这样的文件:
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
它将替换所有出现的“换行符!”与“换行符!”。
现在我尝试只挑选出“换行符!”周围有 \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
用空字符替换新行字符。
所以我的问题是——如何匹配这个模式(我不想在正则表达式's@pattern@replacement@flags'构造之外编写任何perl)?
是否可以匹配这个空字符?我确实尝试过:
perl -0p -e 's@(?<=\0)Newlines!(?=\0)@NEWLINES!@g' input.txt
没有效果。
谁能告诉我如何在 perl 中匹配换行符?是否处于-0
模式?或者我应该使用像 awk 这样的东西? (我从sed
开始,但即使使用-r
,它似乎也没有向前/向后支持。我转向perl,因为我根本不熟悉awk )。
干杯。
(PS:这个问题并不是什么我之所以追随,是因为他们的问题与 .+
匹配换行符有关)。
Question
Suppose I have a file like this:
I've got a loverly bunch of coconut trees.
Newlines!
Bahahaha
Newlines!
the end.
I'd like to replace an occurence of "Newlines!" that is surrounded by blank lines with (say) NEWLINES!. So, ideal output is:
I've got a loverly bunch of coconut trees.
NEWLINES!
Bahahaha
Newlines!
the end.
Attempts
Ignoring "surrounded by newlines", I can do:
perl -p -e 's@Newlines!@NEWLINES!@g' input.txt
Which replaces all occurences of "Newlines!" with "NEWLINES!".
Now I try to pick out only the "Newlines!" surrounded with \n:
perl -p -e 's@\nNewlines!\n@\nNEWLINES!\n@g' input.txt
No luck (note - I don't need the s
switch because I'm not using .
and I don't need the m
switch because I'm not using ^
and $
; regardless, adding them doesn't make this work). Lookaheads/behinds don't work either:
perl -p -e 's@(?<=\n)Newlines!(?=\n)@NEWLINES!@g' input.txt
After a bit of searching, I see that perl
reads in the file line-by-line (makes sense; sed
does too). So, I use the -0
switch:
perl -0p -e 's@(?<=\n)Newlines!(?=\n)@NEWLINES!@g' input.txt
Of course this doesn't work -- -0
replaces new line characters with the null character.
So my question is -- how can I match this pattern (I'd prefer not to write any perl beyond the regex 's@pattern@replacement@flags' construct)?
Is it possible to match this null character? I did try:
perl -0p -e 's@(?<=\0)Newlines!(?=\0)@NEWLINES!@g' input.txt
to no effect.
Can anyone tell me how to match newlines in perl? Whether in -0
mode or not? Or should I use something like awk
? (I started with sed
but it doesn't seem to have lookahead/behind support even with -r
. I went to perl because I'm not at all familiar with awk).
cheers.
(PS: this question is not what I'm after because their problem had to do with a .+
matching newline).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
以下应该适合您:
Following should work for you:
我认为你处理事情的方式导致你以一种行不通的方式组合可能的解决方案。
如果您使用内联编辑标志,您可以这样做:
我将 \n 加倍,以确保您只获得上方和下方带有空行的内容。
I think they way you went about things caused you to combine possible solutions in a way that didn't work.
if you use the inline editing flag you can do it like this:
I have doubled the \n's to make sure you only get the ones with empty lines above and below.
如果文件足够小,可以一次全部放入内存中:
否则,保留最后三行读取的缓冲区:
If the file is small enough to be slurped into memory all at once:
Otherwise, keep a buffer of the last three lines read: