Hatena::ブログ(Diary)

chalcedonyの外部記憶装置・出張版 RSSフィード

2009-09-07

正規表現の先読みと後読みはどっちがどっちだかわかりにくいんだよ!(追記あり)

といつも思うので、自分用にメモすることで覚えようという魂胆です。

以下はInDesign CS4の正規表現について記述します(たしかCS3から使えたような気がする)。

結論から

名前英語で位置演算子
後読みlookbehindマッチパターンよりの部分(?<=) 肯定
(?<!) 否定
先読みlookaheadマッチパターンよりの部分(?=) 肯定
(?!) 否定

肯定の場合はパターンの前が「=」、否定の場合は「!」。

英語を見ると「後読み」「先読み」の訳語も納得できそうな気はするのですが、やっぱりわかりにくいです。背後と前方……とか言うとまた混ざるし!

「つぎの電車」と「こんどの電車」はどっちが早く発車するかみたいな感じに似ていますな。

別に演算子さえ覚えてしまえば名前は意識しなくてもよさそうなのですが、せっかくInDesignには正規表現の記述支援機能がついてるので、どうにか慣れておきたいところです。

先読みと後読みは便利

テキストデータがあって、あるパターンをもった文字列を探したいけど、その中でも「後ろに/前に決まったパターンの文字列がある場合だけ」マッチさせたい、みたいなときに活躍します。

例えば「2009年9月7日19時00分〜9月17日8時30分」とかいうテキストがあって、「○時」の数字だけ取り出したい場合は「直前に『日』があって、直後に『時』がある1桁以上の数字」を検索できればOK。

これを正規表現で書くと

(?<=日)\d+(?=時)

こうなります。

(?<=日)後読み部分
\d+マッチ部分
(?=時)先読み部分

ですね。

先読みと後読みは便利その2

先の例、検索で場所を探したいだけなら、実は後読みだの先読みだの考える必要もなかったりします。

日\d+時

だけでも検索には引っかかる。

ただし、そのときのマッチ文字列は「日19時」と「日8時」。一方先読み/後読みを使った場合、マッチ文字列は「19」「8」になります。先読み/後読みの部分は除外されてます。

この差は大きいです。例えば見つけた数字の修正をしたい場合でも、前者だと数字のところまでカーソルを動かさなければなりませんが、後者ならそのまま数字を打ち込めばいいわけです。

もしくは、数字の部分だけに文字スタイルを適用したい場合も、後者ならば置換文字列に「$0」(「見つかったテキスト」)を入力して、置換形式のところで文字スタイルを指定して置換すればいいだけ。いちいち数字部分を選択しなおしてスタイル適用、が必要ありません。

あと、例のアレ

CS4の「正規表現スタイル」。これを使うときはスタイルを設定したい文字列だけを厳密に取り出す必要があるので、先読み/後読みの使いこなしが前提になりますね。

正規表現スタイルは非常に気に入っている機能*1なので熱く語りたいところですが、まあ、いつかそのうち。

これだけ書けば

いい加減私のスカスカな脳ミソでも覚えただろう(`・ω・´)

『後読みが前、先読みが後ろ!』 ……やっぱりわかりにくい!! ><

追記(2009/09/08)

id:seuzoさんからコメントをいただいて、もうちょっとだけわかった気がしたので追記しておきます。

「後読み」のことを「戻り読み」ともいいます。

(?=re)先読み指定があると、

まだ読んでいない部分を先読みしてマッチしたら全体のマッチを成功させます。

(?<=re)後読み指定があると、

マッチ部分の後ろまで戻って、マッチしたら全体のマッチを成功させます。

       |
   \  __  /
   _ (m) _ピコーン
      |ミ|
    /  `´  \
     ('A`)
     ノヽノヽ
       くく

こうかな?

f:id:chalcedony_htn:20090908181152j:image

マッチ部分を基準にして、データ処理の流れの「先を読む」か「後ろに戻る」か。

やっぱり英語のほうがわかりやすい気がするけど*2、これでなんとか覚えられそうです。日本語ムズカシネー

*1:実を言えばCS4導入の一番の動機がコレ

*2:日本語の場合「先手」「後手」という言葉もあるし、って自分で混乱させているな

seuzoseuzo 2009/09/07 20:38 「後読み」のことを「戻り読み」ともいいます。(そしてさらに混乱に拍車を...
ちなみに「後読み」は「アトヨミ」と読みます。

正規表現エンジンは、マッチに出会って...
(?=re)先読み指定があると、
まだ読んでいない部分を先読みしてマッチしたら全体のマッチを成功させます。
(?<=re)後読み指定があると、
マッチ部分の後ろまで戻って、マッチしたら全体のマッチを成功させます。
つまり、あくまで正規表現エンジンにとってマッチの先か後かってことなんですね。

chalcedony_htnchalcedony_htn 2009/09/08 18:20 >seuzoさん
コメントありがとうございました!
戻り読みというヒントをいただいて少し理解が進んだので、追記してみました。処理が進んでいく方向を意識すれば迷わずに済みそうです。

milligrammemilligramme 2009/09/09 14:34 電車の進行方向を向かないとドアは反対側が開くみたいな。と図をみて一人ピコ〜ン

Uske_SUske_S 2016/05/17 19:40 先読み・後読みを使う場合、検索条件に文字スタイルなどを登録してしまうと、置換結果では除外されるその条件部分もその文字スタイルになっていないとヒットしないです(たしか)。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証