5

(シェルから)perlで改行間で一致させる方法を考え出そうとしています。続く:

(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、正規表現の最後に an を配置すると、次のようになります。

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 呼び出しフラグですか?

4

5 に答える 5

12

-p入力を 1 行ずつループします。ここで、「行」は$/、入力レコード区切り文字である で区切られます。デフォルトでは改行です。$_マッチングのためにすべての 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
]

これらの両方のフラグに関する情報については、perlrun のコマンド スイッチを参照してください。-l(dash-ell) も役立ちます。

于 2012-12-18T07:01:50.650 に答える
2

問題は、ワンライナーが一度に 1 行ずつ動作することです。正規表現は問題ありません。

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;
于 2012-12-18T07:04:30.947 に答える
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;'

このソリューションにはより多くの文字が含まれていますが、他の読者にとってはもう少し理解しやすいかもしれません (3 か月後にあなたになるでしょう ;-D )

于 2012-12-18T19:47:09.157 に答える
1

実際、ワンライナーは次のようになります。

while (<>) {

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

これは、正規表現が入力の最初の行でのみ機能することを意味します。

于 2012-12-18T07:01:57.610 に答える
0

一度に 1 行ずつ読んでいるのに、複数行にまたがる何かとどのように一致すると思いますか?

「行」を「ファイル」に再定義するために追加します(改行を一致-0777させるために /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
]
于 2012-12-18T12:26:50.460 に答える