ご無沙汰の更新となってしまいました。
もともとInDesignのTipsをまとめて同人誌にしようと思っていたのですが、なかなかまとまって書くタイミングがないので不定期的にブログ記事にしていこうと思います。
今回はその一発目で、正規表現の話です。
桁区切りカンマの正規表現
正規表現
割りと悩ましい3桁区切りカンマの挿入について、過去にDTP Transitさんがツイートされてました。
#正規表現知恵袋
— DTP Transit (@DTP_Transit) 2020年1月29日
・ユースケース:3桁以上の数字に桁区切りのカンマを付ける
・検索文字列:(\d{1,3})(?=(?:\d{3})+(?!\d))
・置換文字列:\1,
・アプリケーション:InDesign、Jedit Ω、Keyboard Maestro pic.twitter.com/OboMWw3vlT
検索:(\d{1,3})(?=(?:\d{3})+(?!\d))
置換:$1,
それとは別に、先日、某掲示板にてもう少しシンプルなものが紹介されていました。
検索:(\d+?)(?=(\d{3})+(?!\d))
置換:$1,
どちらも3桁区切りのカンマを挿入できます。
たまたまですが、自分はここで紹介されたものと同じものを使っていました*1。
ほとんど違いがないので後者だけ((\d+?)(?=(\d{3})+(?!\d))
)少し分解してみますと、
(\d+?)
:連続する数字(最短一致)、キャプチャされ置換時$1
の対象(\d{3})+(?!\d)
:左が後ろに続く場合、上記がマッチする(キャプチャされない)- この正規表現は「後続に数字が存在しない、『3つ連続する数字』の連続(最長一致)」
- 否定先読みは、文字列が存在しない場合でも対象になる*2
と、正規表現自体はおよそこんな意味です。
挙動の説明
この正規表現((\d+?)(?=(\d{3})+(?!\d))
)について、少し挙動を分析してみましょう。見本として、InDesignにて下図の文字列を用意しました。
正規表現を確認すると、肯定先読みの前、(\d+?)
この部分をまず見つけます。
+?
は最短一致なので、最初の数字にマッチするわけですね(★)。
ここから、肯定先読み部分((?=(\d{3})+(?!\d))
)にマッチするか調べます。
上図の通り、連続する3つの数字と数字以外、という組み合わせ条件にマッチします。
肯定先読み部分のチェックが終わると、元の検索位置(つまり★の直後)まで戻って検索を再開します。
こんな具合で、うまく3桁の区切りにカンマを挿入できるわけです。
ちなみに
掲示板で(\d)(?=(\d{3})+(?!\d))
が期待通りマッチしないと書かれていましたが、これはおそらくInDesignの不具合のような気がしてます。
CotEditorなどほかのエディタではマッチするからです。
参考文献
- 正規表現:最短一致でマッチさせる表現 | WWWクリエイターズ
最短一致、最長一致という用語について確認した(最終アクセス:2023年3月15日) - 正規表現:文字列を「含まない」否定の表現まとめ | WWWクリエイターズ
否定先読み(否定戻り読み)について確認した(最終アクセス:2023年3月15日)
*1:過去の記事にも桁区切りカンマの正規表現を書きましたが、こっちはマッチしないケースがあるので使っていませんでした。ということで記事も直しています。
InDesignで数字3桁区切りをする正規表現(メモ書き) - DTPab
*2:例えば、前掲注の僕の過去の記事では [^0-9] としていましたが、これは文字列として存在しないとマッチしないので悪手でした