日本翻訳連盟(JTF)

翻訳の手作業を効率化する「正規表現」

第3回:最長一致と最短一致

翻訳者、JTF副会長 高橋 聡

今回は、第2回の最後に出しておいた "宿題" の答えの解説から始めます。お題はこうでした。

  • 「インタフェース」「インターフェース」「インターーフェース」という3種類の表記が原稿に混在している。
  • 以下3種類のパターンの検索を試す。

 インター*フェース(アスタリスク)
 インター+フェース(プラス)
 インター?フェース(疑問符)

  • 結果は以下のようになる。

 アスタリスク(*)→「インタフェース」「インターフェース」「インターーフェース」にヒット。
 プラス(+)→「インタフェース」にはヒットせず、他の2つにヒット。
 疑問符(?)→「インターーフェース」にはヒットせず、他の2つにヒット。

なぜこのような動作になるのか、ひとつずつ考えてみます。まずアスタリスク(*)、これは「直前のパターン0回以上」にヒットするのでした。したがって、

 インター*フェース

と指定した場合、「直前のパターン」が「タ」の後ろの長音符号(ー)で、それが「0回以上」あるパターンにヒットするという指定です。「インタフェース」は「タ」の後ろに長音がありません。「0回以上」は0回も含むので、これもヒットします。「インターフェース」は「タ」の後ろに長音があって、それが「0回以上」ですから当然ヒットし、「インターーフェース」にもやはりヒットします(上限の指定はない)。

コンピューターの内部的な動きからもう少し説明すると、こういうことになります。文字列を検索するときには、先頭の1文字目から順に、一致するかどうかを確認していきます。よって、

 インター*フェース

という検索なら、まず「インタ」までの3文字は問題なく一致する。その次の長音(ー)は「なくてもいいし、いくつあってもいい」というチェックになる。残りの「フェース」はそのまま一致する。だから、3つのバリエーションすべてにヒットするわけです。

次はプラス(+)で、これは「直前のパターン1回以上」でした。

 インター+フェース

「インタ」までの3文字が一致するところは同じ。その次の長音(ー)は、「1回以上」出現していなければならないので、「タ」の後ろに長音がないという段階で、「インタフェース」はヒットしないと判定されます。「インター」はヒットし、「インター―」もヒットします。もし「インター―――――」があったら、それにもやはりヒットします(上限の指定はない)。

最後は疑問符(?)で、これは「直前のパターンが0回または1回」でした。

 インター?フェース

「インタ」までの3文字が一致するところは上の2つと同じ。その次の長音(ー)は、「0回または1回」です。0回でもいいので、「タ」の後ろに長音がなくてもヒットします。1回でもいいので、「ター」もヒットします。しかし、今度は「1回」であって「1回以上」ではないので、「ターー」という形(長音がダブり)にはヒットしません。

というわけで、答え合わせとしてはくどいくらい細かく説明しました。というのも、この「0回」とか「0回以上」の意味、「1回以上」と「1回」の違いが、今回わりと重要になるからです。

さて、今回のサブタイトルは「最長一致と最短一致」です。キーワードとしては、第1回の一覧表に出ています。その一覧表にもある例を使って説明します。例として分かりやすいのは、カギカッコ「」とかHTMLファイルなどのタグ<>で囲まれた部分を検索する場合です。タグを扱う人は少ないかもしれないので、「」で囲まれた部分を検索する例にしてみましょう。

前後のカギカッコで囲まれていて、中はどんな文字でもいいのだから――このように考えていきます。正規表現を覚えて使えるようになるためには、こうやって自分で考えていく過程が大切です。最初のうちは、どこかに書かれているパターンをコピペして使うだけでもいいのですが、検索したい条件を自分で考えながら検索文字列を指定し、失敗して修正して……というプロセスを繰り返すのが一番の勉強になります。

前後のカギカッコで囲まれていて、中はどんな文字でもいいということは、任意の1文字とその繰り返しをカギカッコで囲めばいい――こういう結論にたどり着けたでしょうか。任意の文字はピリオド(.)、繰り返しはアスタリスク(0回以上)かプラス(1回以上)か疑問符(0回または1回)です。それぞれ試してみましょう。今回のこの連載記事をコピーして秀丸エディタ上に貼り付けるとちょうどいいかもしれません。

 「.*」
 「.+」
 「.?」

それぞれ、どんな結果になったでしょうか。どれもうまくいきません。

「.*」と「.+」は、どちらも上のようにヒットしているはずです。「」の1組だけ、たとえば「直前のパターン」とか「タ」だけではなく、最初の1組から始まって、同じ行内の最後の1組である「インターーフェース」までヒットしているのです(ここでいう行とは改行記号までを指しています。上の図では6行あるように見えていますが、これは右端で折り返しているだけです。このように、改行記号までをひとつの単位と考えた行を論理行といいます)。

また、「.?」だと

このように「」の中が1文字の場合しかヒットしません。なぜこうなってしまうのか、ちょっと考えてみてください。うまくいかない理由を正確に考えられるようになれば、正規表現の勉強は着実に進んでいるといえます。疑問符は「直前のパターンが0回または1回」なので、開きカギカッコ(「)の後ろに0文字か1文字あって閉じカギカッコ(」)があればそれで検索終わりになります。

さて、「.*」つまりピリオドとアスタリスクの組み合わせは、「任意の1文字」が「0回以上」出現するパターンです。「.+」つまりピリオドとプラスの組み合わせは、「任意の1文字」が「1回以上」出現するパターンです。そして、「任意の1文字」はどんな文字でもいいことを思い出してください。そう、どんな文字でもいいわけですから、それにはカギカッコ「」自体も含まれてしまうことになります。コンピューターは、1文字ずつ検索条件との一致を考えていくので、最初の開きカギカッコ(「)が見つかったら、そこから順々に一致するかしないかを判定していき、

 「
 「直
 「直前
 「直前の
 「直前のパ
 「直前のパタ
 「直前のパター
 「直前のパターン
 「直前のパターン」

ここまで一致すると判断します。閉じカギカッコ(」)まで見つけましたが、閉じカギカッコは「任意の1文字」のひとつとしてヒットしているにすぎません。つまり、

 「.*」または「.+」

という検索条件のなかの閉じカッコ(」)にヒットしたわけではないのです。閉じカギカッコも任意の1文字にすぎないので、検索はここで終わらずに続いていきます。

 「直前のパターン」が
 「直前のパターン」が「
 「直前のパターン」が「タ
 「直前のパターン」が「タ」
 「直前のパターン」が「タ」の
 「直前のパターン」が「タ」のう
 「直前のパターン」が「タ」のうし
 「直前のパターン」が「タ」の後ろ……

こうして、えんえんと一致すると判断されてしまいます。最後は、同じ論理行内で最後に出現する

 「インターーフェース
 「インターーフェース」

まで見つけた段階でようやく、ここにある閉じカギカッコが検索条件の中の閉じカギカッコに一致したと判断されます。

できるだけ分かりやすく説明したつもりですが、それでもまだ、なんかややこしいですよね。このように「任意の文字」を広く解釈して(コンピューターにしてみれば、別に "広い" わけではない。厳密に解釈しているにすぎないのですが)、一致するかぎりどんどん一致するとみなしていく。こういう一致のしかたが、「最長一致」です。欲張りな一致、greedyな一致なので、英語では "greedy match" と呼ぶことがあります。実に分かりやすい語感です。

ちなみに、同じ検索をWordのワイルドカードでやってみるとどうなるでしょう。Wordの場合、同じ条件を指定する検索パターンは

 「*」(アスタリスク)、または
 「?@」(疑問符とアットマーク)

です。この記事を、Wordファイルに貼り付け、[ワイルドカード]をオンにして検索してみてください。こちらは、上のようにえんえんと長い範囲が一致したりせず、

このように、ちゃんと「」の1組ずつがヒットします。Wordのワイルドカードは、秀丸エディタの正規表現と違って、「最短一致」がデフォルトなのです。検索パターンが最短の形で見つかったらそれでおしまい。欲張りとは正反対のなまけ者です。英語では "lazy match" といいます。最長一致と最短一致のどちらをデフォルトにするのが良いかということではなく、これは単に設計思想の違いです。

では、秀丸エディタの正規表現で最短一致させるにはどうすればいいか。ここでまた疑問符が登場します。といっても、

 「.?」

これだと「直前のパターンが0回または1回」なので、上の実験で分かったように「」の中が1文字の場合しかヒットしません。実は、アスタリスクまたはプラスと疑問符を組み合わせます。

 「.*?」……ピリオド、アスタリスク、疑問符=直前のパターン0回以上(最短)
 「.+?」……ピリオド、プラス、疑問符=直前のパターン1回以上(最短)

つまり、今回までに何度も使ったアスタリスクとプラスの後ろに疑問符を指定すると、それで最短一致になるということです。これを試してみれば、当初の目的どおり、「」で囲まれた1組ずつを検索できるようになります。

IT分野の翻訳者などは、HTMLタグを含むファイルを扱う機会が多いと思います。そのファイルをチェックするときにタグが邪魔になるので、今回の検索パターンを応用すればタグを一括削除することができます。そのほか、全角丸カッコ( )で囲まれた部分なども検索できます(半角丸カッコはうまくいかないかもしれません。理由は、いずれ判明します)。

(次回につづく)

第1回:正規表現とは何か

第2回:任意の文字と繰り返しの指定

○執筆者プロフィール

高橋 聡(たかはし あきら)

CG以前の特撮と帽子と辞書をこよなく愛する実務翻訳者。フェロー・アカデミー講師。日本翻訳連盟(JTF)理事・副会長。学習塾講師と雑多翻訳の二足のわらじ生活と、ローカライズ系翻訳会社の社内翻訳者生活を経たのち、2007年にフリーランスに。現在はIT・マーケティングなどの翻訳を手がけており、翻訳フォーラム(fhonyaku.jp)などの翻訳者グループで情報発信も行う。訳書に『機械翻訳:歴史・技術・産業』(森北出版)、『現代暗号技術入門』『イーサリアム 若き天才が示す暗号資産の真実と未来』(ともに日経BP)など。著書に『翻訳者のための超時短パソコンスキル大全』(KADOKAWA)、共著に『翻訳のレッスン』(講談社)がある。

共有