【问题标题】:Perl does not match multiple linesPerl 不匹配多行
【发布时间】:2020-08-13 13:33:38
【问题描述】:

我要匹配:

Start Here Some example
text covering a few
lines. End Here

所以我愿意

$ perl -nle 'print $1 if /(Start Here.*?)End Here/s'

然后粘贴上面的文本和ctr-D。它与 cmd 不匹配 - 但它在文件脚本中匹配。为什么?

【问题讨论】:

  • 您正在逐行读取文件,因此无法匹配多行,因为$_ 一次只能包含一行。而是将文件读入一个字符串,或逐段读取
  • 所以我可以简单地将undef 放在$/ 的开头,并通过空格分隔的所有单词进行正则表达式?
  • 你所说的是什么意思?"将通过所有单词进行正则表达式..."
  • 你也可以像这样运行你的脚本perl -0777 -nle ....
  • 我的意思是,如果$/ 是undef,$_ 不再是一行?或者我怎样才能在$_ 中删除文件,这样我就可以匹配我尝试过的正则表达式?

标签: shell perl


【解决方案1】:

使用 -0 命令行开关将输入记录分隔符 ($/) 更改为 null。

perl -0777nle 'print $1 if /(Start Here.*?)End Here/s' <<END
Start Here Some example
text covering a few
lines. End Here
THE_END

man perlrun

-0[八进制/十六进制]
将输入记录分隔符 ($/) 指定为八进制或 十六进制数。 […] 任何 0400 或更高的值都会导致 Perl 读取整个文件,但按照惯例,值 0777 是通常用于此目的的值。

man perlvar

IO::Handle->input_record_separator(EXPR)
$INPUT_RECORD_SEPARATOR
$RS
$/
输入记录分隔符,默认为换行符。这影响了 Perl 关于“线”的概念。 [...] 您可以将其设置为 [...] "undef" 以通读文件末尾。

【讨论】:

    【解决方案2】:

    正如其他人所解释的那样,您一次读取一行文件,因此多行匹配永远不会起作用。

    一次读取一行文件通常是最好的方法。所以我们可以使用“flip-flip”操作符来做到这一点:

     $ perl -nle 'print if /Start Here/ .. /End Here/' your_file_here
    

    【讨论】:

    • 但是怎么可能使用/Start Here/,但是在它之后使用一行(我不想在该行使用/Start there/,因为前面的匹配更好),如何我可以使用$. 行号或其他任何东西来实现这一点吗?
    • 或者如果我只想编辑触发器正则表达式行指定范围内的一行?因为,如果在while循环中使用,编辑的效果将是范围内的所有行。如何指定范围中的特定行?
    • 对不起,我做到了,只是在条件匹配指定行中添加了另一个正则表达式
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多