perl中的多行替换扩展表达式不起作用

Multiline replace in perl with extended expressions not working

我正在尝试解析以下多行字符串(以 开头)并将其注释掉。

    -->
<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />
<!-- A "Connector" using the shared thread pool-->

所以我尝试使用以下方法:

perl -i.bak -pe 'BEGIN{undef $/;}
        s/
            \s+ #space at beginning of line
            (<Connector\s+ #connector
             port=\"8080\"\s+  #port
             protocol=\"HTTP\/1\.1\" #protocol
             \n  #newline
            \s+connectionTimeout=\"20000\"\n # space, connection timeout, then newline
            \s+redirectPort=\"8443\" #redirect port
            \/> # end of connector entry in file
            ) # end capture for 
        /
            <!---->
        /msx
    ' server.xml

diff server.xml server.xml.bak

但是 diff 输出什么也没显示。知道我在这里遗漏了什么吗?

我想我明白了。

perl -i.bak -pe 'BEGIN{undef $/;}
        s/
            --> #preceding line ends a comment, with newline at end
            \s+ #space at beginning of line
            (<Connector\s+ #connector
             port=\"8080\"\s+  #port
             protocol=\"HTTP\/1\.1\" #protocol
            \s+connectionTimeout=\"20000\" # space, connection timeout, then newline
            \s+redirectPort=\"8443\" #redirect port
            \s+   #space
            \/> # end of connector entry in file
            ) # end capture for 
        /
            -->\n<!--  -->
        /msx
    ' server.xml

diff server.xml server.xml.bak
~

不要使用 BEGIN 块。在文本文件中插入的正常方法是使用 -0 开关。这会将输入记录分隔符设置为空字符。如果文件中有任何可能存在空值,请使用 -0777.

如果您确切知道搜索文本是什么,就不需要像您写的那么复杂的东西。 Perl 涵盖了该用例。 \Q \E 运算符自动引用任何可能有问题的字符,但仍允许进行变量替换。
$foo = 'f.oo bar$'; print qr/\Q$foo\E/;
(?^:f\.oo\ bar$)

$pattern = qr{\Q<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />\E};
$text =~ s/($pattern)/<!--  -->/;

我看到你想用命令行来做,所以它会像这样。

perl -i.bak -lp0e '$pattern = qr{\Q<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />\E};
s/($pattern)/<!--  -->/; ' FILE

您输入的代码只会执行一次,因为输入只有“一行”。

如果空格的数量有回旋余地,您可以对模式本身进行动态替换。

$pattern = qq{\Q<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />\E};
# Translate runs of escaped whitspace into a single \s+
$pattern =~ s/(?:\\s)+/\s+/g;
$text =~ s/($pattern)/<!--  -->/;

HTH