Hatena::ブログ(Diary)

名もないテクノ手 このページをアンテナに追加 RSSフィード Twitter

EPUB版『InDesign者のための正規表現入門』

InDesignのTips一覧

2009-08-31

[][][][]「正規表現スタイルで(〜)内の文字を小さくする」【入れ子編】

先日のDTP Booster 005において、「正規表現スタイルで(〜)内の文字を小さくする」Tipsを紹介しました。すなわちこの時の正規表現はこんな感じ:

(.+?)

通常の(〜)内であれば、これで大丈夫です。しかし、「○(○(○○))○」のように(〜)が入れ子になっている場合だと、これだけだとうまくいきません。アンケートにも入れ子だとうまくいかないと書かれていました。

▼結果はこんな感じ(よりわかりやすいように文字を赤くしてあります):

f:id:seuzo:20090830131816p:image

こんな時には正規表現をもう少し工夫しないといけません。まず、入れ子の状態が1度だけの時(だけ)を考えてみます。

([^()\r]*?([^()\r]*?)[^()\r]*?)

▼結果は、入れ子1回の時だけにマッチしています。

f:id:seuzo:20090830131817p:image

では、これを最初のものと選択で繋げてみましょう。

(.+?)|([^()\r]*?([^()\r]*?)[^()\r]*?)

▼結果は、入れ子1回の時の途中でマッチが終わってしまっています。

f:id:seuzo:20090830131818p:image

これは何故かというと、最初のマッチが成功すると次のマッチを探さないからなんですね。最初に1回入れ子を探してみて、それでダメなら入れ子なしを探してみるという順番でないといけません。

ですから、入れ子なしと、入れ子1回の正規表現はこうなります。

([^()\r]*?([^()\r]*?)[^()\r]*?)|(.+?)

▼結果は、こんどはちゃんとマッチしているのがわかります。

f:id:seuzo:20090830131819p:image

さて、まあ、あとはお気づきでしょう。欲張りにも2回、3回の入れ子を想定する場合には、こんな感じになるってこと。分かりやすいように3行で書きましたけれど、InDesign上ではこういう書き方は許されないので、1行に繋げてください。

([^()\r]*?([^()\r]*?)[^()\r]*?([^()\r]*?)[^()\r]*?([^()\r]*?)[^()\r]*?)
|([^()\r]*?([^()\r]*?)[^()\r]*?([^()\r]*?)[^()\r]*?)
|([^()\r]*?([^()\r]*?)[^()\r]*?)
|(.*?)

▼結果は、3回までの入れ子の出現はきちんと処理できています。

f:id:seuzo:20090830131820p:image

一見するとワケワカメですが、パーレンとパレーレン以外の文字をモデル化できれば、あとはその繰り返しなんですね。他にも書き方があるかもしれません。スマートな別解をお持ちの方は教えていただければ幸いです。

うえうえ 2009/09/01 14:23 初めまして。セミナーやブログなどで一方的にお世話になっています。うえと申します。
DTP BOOSTERでアンケートに入れ子の件、書きました。
やっぱり正規表現で探していくしかなさそうですねー。CS3がメインなので組んだ後にGREP検索しています。
CS3でもGREP検索以外に何かあるんじゃないかとモヤモヤしていました。早いレスポンスに感謝します。

seuzoseuzo 2009/09/01 15:00 はい。アンケートを見て書きました。
InDesign CS3とCS4では正規表現エンジンが変わっているようです。
http://d.hatena.ne.jp/seuzo/20081216/1229400198

トラックバック - http://d.hatena.ne.jp/seuzo/20090831/1251644469