1. ホーム
  2. regex

[解決済み] 正規表現による置換で数字を増加させることは可能か?

2023-07-14 04:28:19

質問

正規表現による置換で数字を増加させることは可能ですか?使用しない 評価済み/関数ベースの置換 もちろんです。

この質問は 質問者はテキストエディタで数字を増加させたいと考えていました。 . 正規表現置換をサポートするテキストエディタは、完全なスクリプトをサポートするものよりも多いでしょうから、正規表現が存在するのであれば、それを浮かせるのは便利かもしれません。

また、私はしばしば、実質的に役に立たない問題に対する巧妙な解決策から、きちんとしたことを学んできましたので、興味があります。

私たちが非負の十進整数についてだけ話していると仮定すると、すなわち \d+ .

  • 1回の置換で可能ですか?または、有限回の置換で可能ですか?

  • そうでない場合、少なくとも可能なのは 上界が与えられれば 例えば、9999 までの数字があれば可能ですか?

もちろん、while-loopがあれば可能ですが(while matchedで代用)、ここではループレスのソリューションを目指します。

どのように解決するのですか?

この質問のトピックは、私が以前行ったある特定の実装のために私を楽しませました。 私の解決策は、たまたま2つの置換であるので、私はそれを投稿します。

私の実装環境はsolarisで、完全な例です。

echo "0 1 2 3 7 8 9 10 19 99 109 199 909 999 1099 1909" |
perl -pe 's/\b([0-9]+)\b/0$1~01234567890/g' |
perl -pe 's/\b0(?!9*~)|([0-9])(?=9*~[0-9]*?\1([0-9]))|~[0-9]*/$2/g'

1 2 3 4 8 9 10 11 20 100 110 200 910 1000 1100 1910

説明のために引き離す。

s/\b([0-9]+)\b/0$1~01234567890/g

各数字(#)を0#~01234567890に置き換えます。 最初の0は、9から10への丸めが必要な場合のためです。 01234567890のブロックは、インクリメント用です。 "9 10"のテキスト例は以下の通りです。

09~01234567890 010~01234567890

次の正規表現は個別に記述することができますが、置換回数を減らすためにパイプで結合します。

s/\b0(?!9*~)/$2/g

四捨五入を必要としないすべての数値の前にある "0" の桁を選択して破棄します。

s/([0-9])(?=9*~[0-9]*?\1([0-9]))/$2/g

(?=) は正のルックアヘッド、 \1 はマッチグループ#1です。 つまり、'~'マークまで9が続くすべての数字にマッチし、ルックアップテーブルでこの数字の次の数字を探します。 ルックアップテーブルで次の数字に置き換えます。 したがって、正規表現エンジンが数字を解析すると、"09~" は "19~" そして "10~" になります。

s/~[0-9]*/$2/g

この正規表現は、~ルックアップテーブルを削除します。