各行のファイル内の各単語を逆にするスクリプトを作成しようとしています
- 前:
line1 asdasdfff
- 後:
1enil fffdsadsa
使用:
@lines = split(/\s+/, reverse($old));
バグはどこにありますか?
評価で置換を使用できます。
s/(\S+)/reverse $1/ge for @lines;
これにより、連続するすべての非空白がキャプチャされ、元の逆バージョンに置き換えられます。入出力の例:
I'm a little teapot short and stout
m'I a elttil topaet trohs dna tuots
foobar qwerty aboo
raboof ytrewq ooba
あなたの目標がその場で各単語を逆にすることであるならば、それから行全体を逆にして、それからそれを分割することが問題です。行全体を逆にすると、単語の順序が変わるためです。だからあなたはどちらかが欲しい:
my @lines = reverse split(/\s+/, reverse($old));
また:
my @lines = map { reverse; } split /\s+/, $old;
最初のものは単にリストを逆にし、2番目のものは単語を順番に保ち、それぞれを逆にします。私が要件をどのように表現したかによると、2番目のものはあなたがやりたいことのように見えます。単語をそのままにして、各単語を逆にします。(map-grepチェーンについては、右から左に読み取られ、必要に応じて割り当てに進みます。)
だから、あなたは線を逆にしたい。このような場合は、期待される出力(1行のみを含む)からは明らかではありません。ファイルハンドルの場合、$old
。への引数としては不適切reverse
です。「ダイヤモンド演算子」を使用する必要があります<$var>
:
reverse( <$old> );
すべてのレコード/行をメモリに吸い込み、反転した配列を出力します。これをに渡すとsplit
、問題が発生します。配列のサイズのテキスト表現のみを分割します。数値にはスペースがないため、配列のサイズを含む配列で構成されます。だからあなたは各行を分割したい...
map { [ split /\s+/ ] } reverse( <$old> );
私はそれらを配列に入れたので、ファイル全体を逆にするだけでなく、各行配列は1つの単位として一緒にとどまります。そして、あなたは各単語を逆にする必要があるので分割します。
map { map { reverse; } split /\s+/ } reverse( <$old> );
もちろん、そこにはレコードセパレーターがあるので、それらを考慮する必要があります。chomp
アウターの先頭にを置くだけmap
です。
map { chomp; map { reverse; } split /\s+/ } reverse( <$old> );
また、各グループの最後にレコード区切り文字を追加したい場合があるため、各単語のリストをバンドルする必要があります。
print map { chomp; (( map { reverse; } split /\s+/ ), $\ || $/ ) } reverse( <$old> );
そのため、式を分離してからmap
、現在定義されている出力レコード区切り文字を追加する必要がありました。定義されていない場合は、入力レコード区切り文字を各分割および反転行に追加する必要がありました。