$s = "bla..bla";
$s =~ s/([^%])\./$1/g;
.後ではないすべての出現を%前の文字に置き換える必要があると思います.。
しかし$s、それは:bla.blaですが、そうあるべきですblabla。問題はどこだ?数量詞を使用できることはわかっていますが、この方法で使用する必要があります。
グローバル正規表現が文字列を検索しているとき、重複する一致は見つかりません。
文字列の最初の一致は、になりa.、これは。に置き換えられaます。正規表現エンジンが検索を再開すると、次の文字列から開始される.ため、文字列の残りの部分と見なさ.blaれます。正規表現では、文字が一致する必要がある.ため、再度一致することはできません。
代わりに、ネガティブルックビハインドを使用して、前の文字がそうではないというアサーションを実行します%。
$s =~ s/(?<!%)\.//g;
のようなポジティブルックビハインドを使用する場合、それが文字列の最初の文字である場合(?<=[^%])は置き換えられないことに注意してください。.
問題は、/gフラグがあっても、各置換が前の置換が中断したところから探し始めることです。で置き換えようとしa.てaいa.ますが、前の置き換えですでに「飲み込まれている」aため、2番目の置き換えは発生しません。a
1つの修正は、ゼロ幅のルックビハインドアサーションを使用することです。
$s =~ s/(?<=[^%])\.//g;
これにより、文字列の最初の文字では.なく、前に。が付いていない文字がすべて削除され%ます。
しかし、実際にはこれが必要な場合があります。
$s =~ s/(?<!%)\.//g;
これにより、文字列の最初の文字であっても、先頭にない.ものはすべて削除されます。%
後読みよりもはるかに簡単な方法は、次の方法を使用することです。
$s =~ s/([^%])\.+/$1/g;
これは、何もない以外の文字の後の1つ以上のドットの文字列を置き換えます%。