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

发布于 2025-01-02 13:33:10 字数 1582 浏览 0 评论 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

萌︼了一个春 2025-01-09 13:33:10

以下应该适合您:

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

Following should work for you:

perl -0pe 's@(?<=\n\n)Newlines!(?=\n\n)@NEWLINES!@g'
眼泪都笑了 2025-01-09 13:33:10

我认为你处理事情的方式导致你以一种行不通的方式组合可能的解决方案。

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

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

我将 \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:

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

I have doubled the \n's to make sure you only get the ones with empty lines above and below.

叶落知秋 2025-01-09 13:33:10

如果文件足够小,可以一次全部放入内存中:

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

If the file is small enough to be slurped into memory all at once:

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

Otherwise, keep a buffer of the last three lines read:

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 }'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文