perl 正则表达式不匹配带有换行符的字符串\n [英] perl regex not matching string with newline character \n

查看:68
本文介绍了perl 正则表达式不匹配带有换行符的字符串\n的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to use perl (v5.14.2) via a bash shell (GNU Bash-4.2) in Kubuntu (GNU/Linux) to search and replace a string that includes a newline character, but I'm not succeeding yet.

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

Here's the text file I'm searching:

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

hello
kitty

blah blah blah

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

When I use a text editor's (Kate's) search-and-replace functionality or when I use a regex tester (http://regexpal.com/), I can easily get this regex to work:

hello\nkitty

但是在命令行中使用 perl 时,以下命令均无效:

But when using perl in the command line, none of the following commands have worked:

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

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

Actually, I got desperate and tried many other patterns, including all of these (different permutations in the "single-line" and "multi-line" modes):

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

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

(I also tried using \r \r\n \R \f \D etc., and global mode as well.)

谁能发现问题或提出解决方案?

Can anyone spot the issue or suggest a solution?

推荐答案

尝试这样做,我通过修改输入记录分隔符(默认为换行符)使这成为可能:

Try doing this, I make this possible by modifying the input record separator (a newline by default) :

perl -i -p00e 's,hello\nkitty,newtext,' prac1.html

来自 perldoc perlrun :

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

-0[octal/hexadecimal]

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

specifies the input record separator ($/ ) as an octal or hexadecimal number. If there are no digits, the null character is the separator. Other switches may precede or follow the digits. For example, if you have a version of find which can print filenames terminated by the null character, you can say this:

find . -name '*.orig' -print0 | perl -n0e unlink

特殊值 00 将导致 Perl 在段落模式下吞咽文件.任何 0400 或更高的值都将导致 Perl 吞食整个文件,但通过约定值 0777 是通常用于此目的的值.

The special value 00 will cause Perl to slurp files in paragraph mode. Any value 0400 or above will cause Perl to slurp files whole, but by convention the value 0777 is the one normally used for this purpose.

这篇关于perl 正则表达式不匹配带有换行符的字符串\n的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆