各行の先頭から2つのスペースをそれぞれタブに置き換えたいと思います。私は次のことを試しました:
s/^(\s{2})+/\t/gm;
それはうまくいきませんでした。
ファイルを1行ずつ読んでいる場合:
$line =~ s/\G[ ]{2}/\t/g;
ファイル全体を丸呑みした場合:
$file =~ s/(?:\G|^)[ ]{2}/\t/mg;
数量+
詞は「1つ以上の」を意味し\s{2}
、「正確に2つの空白文字」を意味することに適用されることに注意してください。簡単な例として、0から10のスペースの文字列を作成し、それらを同様のパターンと照合しようとするプログラムについて考えてみます。
#! /usr/bin/env perl
use strict;
use warnings;
for (0 .. 10) {
$_ = " " x $_;
printf "%-13s %s\n", "[$_]:", /^(\s{2})+$/ ? "match!" : "no match.";
}
出力:
[]: 歯が立たない。 [ ]: 歯が立たない。 [ ]: マッチ! [ ]: 歯が立たない。 [ ]: マッチ! [ ]: 歯が立たない。 [ ]: マッチ! [ ]: 歯が立たない。 [ ]: マッチ! [ ]: 歯が立たない。 [ ]: マッチ!
記述されているように、パターンは、論理的な行頭の空白文字の正の偶数を1つのTAB文字に置き換えます。
コードのより広いコンテキストを提供しません。/m
とスイッチの使用から、/g
全体として操作したいテキストの塊、おそらくファイルの内容全体があると思います。以下のプログラムは、ヒアドキュメントを使用してこの想定される状況をシミュレートし、各行の最初の2つのスペースのみをTABで置き換えます。
#! /usr/bin/env perl
use strict;
use warnings;
$_ = <<EOText;
Three
Two
Four
Five
Zero
One
EOText
s/^ /\t/mg;
# for display purposes only
s/\t/\\t/g;
print;
出力:
\t3つ \ t2 \t4つ \tファイブ 零 1
余分なコメントs///
はコードに残らないことに注意してください。スペースとTAB文字のコントラストを追加するためにあります。
これがあなたのプログラムの唯一の目的である場合、それは簡単なワンライナーになります。内容が変更された新しいファイルを作成するには、次を使用します。
$ perl -pe's / ^ / \t/'入力ファイル>出力ファイル
その場での編集は次のようになります
$ perl -i.bak -pe's / ^ / \t/'入力ファイル
これはどうですか?
my $test_string = " some test stuff\ndivided to\n provide the challenge";
$test_string =~ s/^[ ]{2}/\t/gm;
print $test_string;
説明:\s
実際には単一のシンボルエイリアスではなく、文字の「空白」クラスです。たとえば\n\
、両方が含まれています。\t
スペースのみを置き換える場合は、正規表現でスペースを使用してください。文字クラスを設定する(私だけではなく、読みやすくなります(そして、修飾子/^ {2}/...
で壊れることはありません)。/x
さらに、 2つのスペース記号だけを置き換える場合は、+
数量詞を使用する必要はありません。
更新:2つのスペースをそれぞれ置き換える必要がある場合は、代わりにこれを使用すると思います。
$test_string =~ s#^((?:[ ]{2})+)#"\t" x (length($1)/2)#gme;
...または池上さんの答えのように\Gアンカー。
別の解決策として、/m
修飾子なしでポジティブルックビハインドを使用できます。このようなアプローチは、行の先頭だけでなく、他の何かをチェックする必要がある場合に役立つ可能性があります。そのため、\m
修飾子が役に立たない場合>>
$_ = " 123\n 456\n 789";
s/(?:(?<=^)|(?<=\n))\s{2}/\t/g;
print $_;
上記のコード例では、文字列の先頭または改行文字の後ろにある各/g
二重空白がタブに置き換えられています。\s{2}
(?<=^)
(?: .. | .. )
(?<=\n)
\t