如何匹配perl正则表达式中的换行符?

时间:2012-12-18 06:42:46

标签: regex perl shell

我正在尝试研究如何使用perl(来自shell)匹配换行符。以下内容:

(echo a b c d e; echo f g h i j; echo l m n o p) | perl -pe 's/(c.*)/[$1]/'

我明白了:

a b [c d e]
f g h i j
l m n o p

这是我的期望。但是当我在正则表达式的末尾放置一个/s时,我得到了这个:

a b [c d e
]f g h i j
l m n o p

我期望并希望它打印出来的是:

a b [c d e
f g h i j
l m n o p
]

我的正则表达式有问题,还是我的perl调用标志?

5 个答案:

答案 0 :(得分:10)

-p逐行循环输入,其中“lines”由输入记录分隔符$/分隔,输入记录分隔符默认为换行符。如果您想将所有STDIN粘贴到$_进行匹配,请使用-0777

$ echo "a b c d e\nf g h i j\nl m n o p" | perl -pe 's/(c.*)/[$1]/s'
a b [c d e
]f g h i j
l m n o p
$ echo "a b c d e\nf g h i j\nl m n o p" | perl -0777pe 's/(c.*)/[$1]/s'
a b [c d e
f g h i j
l m n o p
]

有关这两个标志的信息,请参阅Command Switches in perlrun-l(破折号)也很有用。

答案 1 :(得分:2)

问题是你的单行一次一行,你的正则表达式很好:

use strict;
use warnings;
use 5.014;

my $s = qq|a b c d e
f g h i j
l m n o p|;

$s =~ s/(c.*)/[$1]/s;

say $s;

答案 2 :(得分:1)

实际上你的单行看起来像这样:

while (<>) {

     $ =~ s/(c.*)/[$1]/s;
}

这意味着正则表达式仅适用于输入的第一行。

答案 3 :(得分:1)

有多种方法可以做到这一点:既然你一直在阅读“整个文件”,我会亲自删除-p修饰符,明确地啜饮整个输入,然后从那里开始:

echo -e "a b c d e\nf g h i j\nl m n o p" | perl -e '$/ = undef; $_ = <>; s/(c.*)/[$1]/s; print;'

这个解决方案确实有更多的字符,但对于其他读者可能会更容易理解(三个月后你会这样; -D)

答案 4 :(得分:0)

你一次读一行,所以你怎么认为它可能匹配跨越多行的东西?

添加-0777以将“line”重新定义为“file”(并且不要忘记添加/ s以使.匹配换行符。)

$ (echo a b c d e; echo f g h i j; echo l m n o p) | perl -0777pe's/(c.*)/[$1]/s'
a b [c d e
f g h i j
l m n o p
]