« # 翻訳者のための正規表現~勉強会の解説、その2 | トップページ | # 新・午前十時の映画祭 ~ 『大脱走』 »

2013.04.29

# 翻訳者のための正規表現~勉強会の解説、その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]+ ?[((].+[))]

 ---> 開きカッコ [((]、閉じカッコ [))]、その間にある .+ が任意の文字列です。

さあ、今回最大の難関です。記事のいちばん下に練習用のテキストがあるので、ためしにこのパターンをコピペして検索を実行してみてください。

1304291

こんな風に、数字から、最後の閉じカッコまで一気にヒットしてしまいました。これでは、全体が1回だけ置換されて、とんでもない結果になってしまいます。本当は、

1304292

というようにそれぞれの箇所をヒットさせて、それを置換したいわけです。

どうして、上のスクリーンショットのように広い範囲がヒットしてしまうかというと、その原因は、.+ の部分にあります。このパターンの意味は「任意の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)人以上が死傷する事件が発生した。

----------練習用テキスト・終----------

ふー、疲れた。


でも、こんな風に勉強会の準備をすると、自分でもいい勉強になるんですよね。今回もそれを痛感しました。

03:48 午後 翻訳者のPCスキル |

はてなブックマークに追加

« # 翻訳者のための正規表現~勉強会の解説、その2 | トップページ | # 新・午前十時の映画祭 ~ 『大脱走』 »

トラックバック


この記事へのトラックバック一覧です: # 翻訳者のための正規表現~勉強会の解説、その3:

コメント

この記事へのコメントは終了しました。