Perl命令行无法匹配多行内容,但脚本文件中可行,原因何在?
为什么Perl命令行正则匹配失败但脚本里成功?
这个问题其实和Perl命令行选项的行为细节有关,特别是-n选项的输入处理逻辑,我来给你一步步拆解:
1. 命令行里-n选项的核心行为
-n选项会自动给你的代码套上一个while (<>) { ... }循环,这意味着Perl会逐行读取输入内容——每次只把一行文本放到$_变量中处理,处理完一行再读下一行。
再加上你用的-l选项,它会自动去掉每行末尾的换行符,所以每一行的内容里根本不存在换行符。
2. 正则匹配失败的原因
你的正则表达式/(Start Here.*?)End Here/s里的/s修饰符,作用是让.可以匹配换行符,但问题在于:
在-n的逐行模式下,Start Here和End Here如果不在同一行,它们永远不会同时出现在同一个$_变量里,正则自然找不到匹配的内容。
3. 脚本里能成功的原因
大概率你的脚本没有用逐行读取的逻辑,而是一次性把整个输入内容读进了一个变量中。比如你可能用了类似这样的代码:
local $/; # 将输入记录分隔符设为undef,一次性读取全部内容 my $all_content = <>; print $1 if $all_content =~ /(Start Here.*?)End Here/s;
这时候整个文本(包括所有换行符)都在一个字符串里,/s修饰符就能让.匹配换行,正则自然能成功匹配跨多行的内容。
4. 让命令行正常工作的修改方法
你需要让Perl一次性读取全部输入,而不是逐行。可以用-0777选项,它会把输入记录分隔符设置为undef,一次性读取所有输入到$_中:
perl -0777 -ne 'print $1 if /(Start Here.*?)End Here/s'
现在再输入多行文本并按Ctrl+D结束,就能正确匹配到你想要的内容了。
内容的提问来源于stack exchange,提问作者Herdsman
相关产品推荐
相关产品推荐

