匹配多行并在 perl 正则表达式中打印

Match multiline and print it in perl regex

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

$ 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

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

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

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

我猜你不需要 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»

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

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 修饰符,但有些人更喜欢始终使用它。这些组使正则表达式评估为每个匹配项 return 两个项目的列表。最后,打印用于列表分隔符 ($,) 和列表末尾 ($\) 的值必须设置为 "\n".

版本可以说是 simpler/better 并且更接近上面的解决方案:

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