perl正则表达式不匹配字符串与换行符\n

zer*_*lax 4 regex perl

我试图通过Kubuntu(GNU/Linux)中的bash shell(GNU Bash-4.2)来使用perl(v5.14.2)来搜索和替换包含换行符的字符串,但我还没有成功.

这是我正在搜索的文本文件:

<!-- filename: prac1.html -->

hello
kitty

blah blah blah
Run Code Online (Sandbox Code Playgroud)

当我使用文本编辑器(Kate)的搜索和替换功能或当我使用正则表达式测试器(http://regexpal.com/)时,我可以很容易地使这个正则表达式工作:

hello\nkitty
Run Code Online (Sandbox Code Playgroud)

但是在命令行中使用perl时,以下命令都没有起作用:

perl -p -i -e 's,hello\nkitty,newtext,' prac1.html
perl -p -i -e 's,hello.kitty,newtext,s' prac1.html
perl -p -i -e 's,hello.*kitty,newtext,s' prac1.html
perl -p -i -e 's,hello[\S\s]kitty,newtext,' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,' prac1.html
Run Code Online (Sandbox Code Playgroud)

实际上,我绝望并尝试了许多其他模式,包括所有这些模式("单行"和"多行"模式中的不同排列):

perl -p -i -e 's,hello\nkitty,newtext,' prac1.html
perl -p -i -e 's,hello.kitty,newtext,' prac1.html
perl -p -i -e 's,hello\nkitty,newtext,s' prac1.html
perl -p -i -e 's,hello.kitty,newtext,s' prac1.html
perl -p -i -e 's,hello\nkitty,newtext,m' prac1.html
perl -p -i -e 's,hello.kitty,newtext,m' prac1.html
perl -p -i -e 's,hello\nkitty,newtext,ms' prac1.html
perl -p -i -e 's,hello.kitty,newtext,ms' prac1.html

perl -p -i -e 's,hello[\S\s]kitty,newtext,' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,' prac1.html
perl -p -i -e 's,hello$[\S\s]^kitty,newtext,' prac1.html
perl -p -i -e 's,hello$[\S\s]*^kitty,newtext,' prac1.html
perl -p -i -e 's,hello[\S\s]kitty,newtext,s' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,s' prac1.html
perl -p -i -e 's,hello$[\S\s]^kitty,newtext,s' prac1.html
perl -p -i -e 's,hello$[\S\s]*^kitty,newtext,s' prac1.html
perl -p -i -e 's,hello[\S\s]kitty,newtext,m' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,m' prac1.html
perl -p -i -e 's,hello$[\S\s]^kitty,newtext,m' prac1.html
perl -p -i -e 's,hello$[\S\s]*^kitty,newtext,m' prac1.html
perl -p -i -e 's,hello[\S\s]kitty,newtext,ms' prac1.html
perl -p -i -e 's,hello[\S\s]*kitty,newtext,ms' prac1.html
perl -p -i -e 's,hello$[\S\s]^kitty,newtext,ms' prac1.html
perl -p -i -e 's,hello$[\S\s]*^kitty,newtext,ms' prac1.html
Run Code Online (Sandbox Code Playgroud)

(我也尝试过使用\ r \n \n \n\R\f\D等,以及全局模式.)

有人能发现问题或提出解决方案吗?

Gil*_*not 11

尝试这样做,我通过修改输入记录分隔符(默认情况下换行)来实现这一点:

perl -i -p00e 's,hello\nkitty,newtext,' prac1.html
Run Code Online (Sandbox Code Playgroud)

来自perldoc perlrun:

-0 [八进制/十六进制]

将输入记录分隔符($ /)指定为八进制或十六进制数.如果没有数字,则空字符是分隔符.其他开关可以在数字之前或之后.例如,如果您有一个可以打印由空字符终止的文件名的find版本,您可以这样说:

find . -name '*.orig' -print0 | perl -n0e unlink
Run Code Online (Sandbox Code Playgroud)

特殊值00将导致Perl在段落模式下粘贴文件.任何值0400或更高将导致Perl整个文件,但按照惯例,值0777是通常用于此目的的值.


Blu*_*uby 6

问题是"-p"已经隐式地将这个循环包裹在你的"-e"周围,而"<>"将输入分成几行,所以你的正则表达式永远不会有机会看到多行.

 LINE:
       while (<>) {
           ...             # your program goes here
       } continue {
           print or die "-p destination: $!\n";
       }
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参见perlrun联机帮助页.