# 翻訳者のための正規表現~勉強会の解説、その3
4/23に開催した「十人十色・正規表現入門セミナー」後半の内容の復習、第3回です。
明日から天気が崩れますが、GW後半はまたいい天気になりそうですね。
お題その4
・数字の全角半角、それに続く丸カッコの全角半角が混在しているとき、
ぜんぶ一括して「半角数字 + 半スペ + 半角丸カッコ(この中は任意) + 半スペ」に置換する
【考え方の整理】
・全角半角すべての数字
・数字の直後はスペースがあったりなかったり
・全角半角の開き丸カッコ
・カッコの中身は任意の文字の続き
・全角半角の閉じ丸カッコ
・閉じカッコの直後はスペースがあったりなかったり
【ひとこと】
これはかなり高度な検索/置換になりますので、上の「考え方の整理」にあげたポイントを、順番に作っていくことにしましょう。これを順番に理解していけば、正規表現のマスターもかなりの段階まで進むはずです。
【検索その1】
[0-90-9]+
---> 前半が半角数字、後半が全角数字です。+ を付けて1回以上の出現。
【検索その2】
[0-90-9] ?+
---> もうお分かりですね。「半スペがあったりなかったり」は △? です。
【検索その3】
[0-90-9] ?+[((] または
---> 半スペあり/なしの後に、全角半角の開き丸カッコ。
ここで、今までの内容をちゃんと理解してきた人であれば、[((]の部分に疑問を持った方がいらっしゃるかもしれません。そうです。正規表現を使っているときに半角の丸カッコを指定するには、\( のようにエスケープする必要があったはずですよね。
参照リンク:# 翻訳者のための正規表現~基本その4
はい。その通りです。したがって、上のパターンは
[0-90-9] ?+[\((] または
と書いても同じ機能になります。ところが、[ ] で囲んだ範囲指定の中では、
ピリオド(.)
アスタリスク(*)
プラス(+)
クエスチョンマーク(?)
丸カッコ ( )
はエスケープしなくても、その文字のままとして解釈されるのです。
【検索その4】
[0-90-9]+ ?[((].+[))]
---> 開きカッコ [((]、閉じカッコ [))]、その間にある .+ が任意の文字列です。
さあ、今回最大の難関です。記事のいちばん下に練習用のテキストがあるので、ためしにこのパターンをコピペして検索を実行してみてください。
こんな風に、数字から、最後の閉じカッコまで一気にヒットしてしまいました。これでは、全体が1回だけ置換されて、とんでもない結果になってしまいます。本当は、
というようにそれぞれの箇所をヒットさせて、それを置換したいわけです。
どうして、上のスクリーンショットのように広い範囲がヒットしてしまうかというと、その原因は、.+ の部分にあります。このパターンの意味は「任意の1文字を1回以上繰り返す」ということでした。
さて、ここで指定しようと考えているのは、
全角半角の数字 + 半スペあり/なし + 開きカッコ + 任意の文字列 + 閉じカッコ
というパターンです。たとえば、2013 (平成25) にヒットさせたいわけですから、
2013 …… [0-90-9]+ でヒット
△ …… △? でヒット
( …… [((] でヒット
平成25 …… 任意の文字列 .+ でヒット
) …… [))] でヒット
するはずと想定したわけですが、.+ という指定が「平成25」でストップせず、
任意の文字にヒットするかぎりずーっと
(=次の条件にヒットするまで)ヒットしてしまうのです。
つまり、この例で言うと「~150」のところまでが .+ でヒットし、その後の全角丸カッコ [))] に当たって、そこでようやく止まったということです。
このように、「任意の文字(の複数回出現)」を指定したとき、別の条件が出てくるまでずーっと当たりになってしまう動作を、
最長一致
と言います。英語では、このような性質を greedy と表します。
ではどうするかというと、「任意の文字(の複数回出現)」が必要最小限の回数だけ当たる、
最短一致
(英語では non-greedy)で動作するよう指定します。
[0-90-9]+ ?[((].+?[))]
またクエスチョンマークですね。.+ の後に ? を指定すると、上で想定したとおりの動作になります。
これで検索については、すべてのパターンを網羅できました。これに、区切り \f を入れれば完成です。
【検索その5 ~ 最終形】
[0-90-9]+\f ?\f[((]\f.+?\f[))]
【置換】
\0 \(\3\)
【解説】
・検索パターンについては、上に詳しく説明しました。
・区切り \f は4個入っています。説明すると、
全角半角の数字\f△?\f開きカッコ\f任意の文字列\f閉じカッコ
となっているはずです。
・\0△\(\3\)△ …… 最初の数字 + 半スペ + 半角開きカッコ + 任意の文字列 + 半角閉じカッコ + 半スペ
これで置換してみると ...... うまくいきませんね。スペースと半角カッコの処理はうまくいっているのですが、
全角数字を半角数字に置換
というのは、実は通常の正規表現ではできないのです。[0-9]と範囲指定しているだけですから、ヒットした数字をどの半角数字に置換していいか、までは判断できませんからね。
ということで、実は数字の全角/半角置換となると、これはマクロの領域になってしまいます。
…… というのが、私も佐川さんも共通の見解だったのですが、実は、これがつい最近のバージョンの秀丸エディタ(ver.8.20)からは可能になったのです。
私自身、今回の勉強会の準備をしているとき、初めて知りました。
さすがに長くなったので、これは次回に回します。興味のある方は、秀丸エディタのヘルプで「変換モジュールによる変換の指定」というトピックを調べてみてください。
----------練習用テキスト・始----------
2013 (平成25) 年4月15(現地時間)日、アメリカ北東部・ボストンで開催されていたボストンマラソンのゴール付近で2(あるいは3)回の爆発が起き、100(~150)人以上が死傷する事件が発生した。
----------練習用テキスト・終----------
ふー、疲れた。
でも、こんな風に勉強会の準備をすると、自分でもいい勉強になるんですよね。今回もそれを痛感しました。
この記事へのコメントは終了しました。
コメント