【问题标题】:Match multiline and print it in perl regex匹配多行并在 perl 正则表达式中打印
【发布时间】:2015-04-24 09:24:13
【问题描述】:

我想匹配一个多行正则表达式并只打印匹配的行:

$ cat test.txt
line1
line2
line3
$ perl -ne 'print if /line2.line3/s' test.txt
$

这个正则表达式实际上匹配line2\nline3,但它没有被打印出来。 regex101 verifies 表示匹配。

使用命令开关0777 会打印匹配的行,但也会打印不匹配的行:

$ perl -0777 -ne 'print if /line2.line3/s' test.txt
line1
line2
line3

在替换正则表达式中使用0777 可以按预期工作:

$ perl -0777 -pe 's/line2.line3/replaced/s' test.txt
line1
replaced

我想了解是否可以只打印与多行正则表达式匹配的行?

【问题讨论】:

    标签: regex perl multiline


    【解决方案1】:

    print 不带参数打印$_。如果你使用-0777,整个文件被读入$_,所以如果有匹配,你打印整个文件。如果只想显示匹配的部分,可以使用

     perl -0777 -ne 'print "$1\n" while /(line2.line3)/sg' test.txt
    

    【讨论】:

      【解决方案2】:

      我猜你不需要ifwhile 或正则表达式组。

       perl -0777 -ne 'print /line2\sline3\s/sg' test.txt
      

      输出:

      line2
      line3
      

      正则表达式解释:

      line2\sline3\s
      --------------
      
      Match the character string “line2” literally (case insensitive) «line2»
      Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
      Match the character string “line3” literally (case insensitive) «line3»
      Match a single character that is a “whitespace character” (any Unicode separator, tab, line feed, carriage return, vertical tab, form feed, next line) «\s»
      

      【讨论】:

      • 您能解释一下为什么会这样吗?这个和我上面的命令的唯一区别是这个没有if
      • 您可能需要在正则表达式中添加最后一个换行符。
      • @MertNuhoglu 我猜 choroba 的答案比我的更能解释,它是一个非常简单的 perl 正则表达式,可以打印匹配项。我已经用正则表达式解释更新了我的答案。
      • @choroba 指出,我在末尾添加了 \s。 tks.
      • 另一种选择是perl -0777 -pe 'print unless s/line2.*line3\s//sg' test
      【解决方案3】:

      考虑到行尾的另一个变体可能是:

      perl -0777 -ne '($,, $\) = ("\n")x2; print /(^line2$)\s(^line3$)/msg'
      

      比较:

      $ cat test.txt 
      line1
      line2
      line3
      line1
      line2 line3
      $ perl -0777 -ne 'print /line2\sline3\s/sg' test.txt
      line2
      line3
      line2 line3
      $ perl -0777 -ne '($,, $\) = ("\n")x2; print /(^line2$)\s(^line3$)/gms' test.txt
      line2
      line3
      

      m 修饰符允许在多行上下文中使用^$g 修饰符使正则表达式在字符串上循环。在这种情况下不需要s 修饰符,但有些人更喜欢始终拥有它。这些组使正则表达式评估的列表每次匹配返回两个项目。最后,打印用于列表分隔符 ($,) 和列表末尾 ($\) 的值必须设置为 "\n"

      版本可以说更简单/更好,更接近上述解决方案:

      perl -0777 -ne 'print /line2\nline3\n/sg' test.txt
      

      【讨论】:

        猜你喜欢
        • 2015-02-24
        • 1970-01-01
        • 1970-01-01
        • 2017-01-20
        • 1970-01-01
        • 2017-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多