【问题标题】:How do I search and replace across multiple lines with Perl?如何使用 Perl 搜索和替换多行?
【发布时间】:2013-05-20 12:01:30
【问题描述】:
$ perl --version
This is perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multi

$ echo -e "foo\nbar" > baz.txt
$ perl -p -e 's/foo\nbar/FOO\nBAR/m' baz.txt
foo
bar

我怎样才能让这个替代品起作用?

【问题讨论】:

  • 尝试添加g标志:'s/foo\nbar/FOO\nBAR/gm'
  • @Jerry no,g 选项用于全局行为,与我的问题无关。
  • 正式注明@GabeKopley

标签: regex perl multiline


【解决方案1】:

您可以使用-0 开关更改输入分隔符:

perl -0777pe 's/foo\nbar/FOO\nBAR/' baz.txt

-0777 将分隔符设置为undef-0 单独将其设置为\0,这可能适用于不包含空字节的文本文件。

请注意,/m 是不必要的,因为正则表达式不包含 ^$

【讨论】:

  • 比我的好多了。我不习惯-0 开关,但在这种情况下非常适合。 +1 为此。
  • -0$/ 设置为 "\000" 并将 -0777 设置为 undef,但两者都执行文件 slurp。 :o
  • @Сухой27,没有。 -0 仅在文件不包含 NUL 字符时才删除文件。文本文件通常不包含这些字符。因此,对于文本文件,它通常不会有什么不同,但如果你想把文件吞进去,不管它可能包含什么,那就是你想要的 -0777-0 更多用于处理find -print0grep -lZ(NUL 分隔记录)的输出。比较 printf 'a\0b\0' | perl -l -0 -ne 'print $.'printf 'a\0b\0' | perl -l -0777 -ne 'print $.'
  • 您可以将-0/-z/--null 与 GNU grep 或 GNU sed 一起使用,因为您没有其他选择。它们没有 slurp 模式,但您可以使用 -z 模拟它,只要您可以保证输入不包含 NUL 字符。 (你仍然可以使用pcregrep -M ...gsed ':1;$!{N;b1}...
  • -0-0777 之间的另一个区别是,对于一个空的 baz.txt,您将获得 0 条记录,前者为 1 条记录,后者为 1 条空记录(这里没有区别s/foo\nbar/FOO\nBAR/ 但例如 s/^/prefix/)。
【解决方案2】:

它与-p 开关有关。它一次读取一行输入。因此,您不能对两行之间的换行符运行正则表达式,因为它永远不会匹配。您可以做的一件事是读取所有输入修改变量$/ 并将正则表达式应用于它。一种方式:

perl -e 'undef $/; $s = <>; $s =~ s/foo\nbar/FOO\nBAR/; print $s' baz.txt

它产生:

FOO
BAR

【讨论】:

    猜你喜欢
    • 2021-01-31
    • 2015-08-24
    • 2015-02-20
    • 2010-11-05
    • 2017-01-05
    • 2010-10-29
    • 2018-05-16
    • 2019-05-05
    • 1970-01-01
    相关资源
    最近更新 更多