CATツールで使える正規表現・第9回
この連載では、翻訳の現場で役に立つ正規表現を取り上げながら、memoQやTrados Studio、XTMのようなCATツール(翻訳支援ツール)で利用できる正規表現について解説しています。
前回は、全角文字と半角文字のあいだにスペースがあるパターンとないパターンを検索する正規表現を作りましたが、その正規表現には問題がありました。今回は、正規表現の強力な機能である「先読み」と「後読み」を使って、その問題を解決します。
目次[非表示]
何が問題だったか
まずは前回の問題を確認しましょう。(参照:CATツールで使える正規表現・第8回)
前回は、全角文字と半角文字のあいだにスペースがあるというパターンを検索するために、「全角文字+1文字以上のスペース+半角文字」または「半角文字+1文字以上のスペース+全角文字」を表す正規表現を作りました。ところが、その正規表現で、半角スペースを3つ含む「4 月 1 日」に対して検索すると、「4 月」と「1日」は検索できるのに「月 1」が検索できません。
なぜかといえば、ある文字列にマッチしたあとの検索が、マッチした文字列の直後から始まるからです。この例では、「4 月」が見つかった時点で「月」までが検索済みとなり、次の検索はその後のスペースから始まります。
もし「直前の文字が全角文字であり直後の文字が半角文字であるスペース」や「直前の文字が半角文字であり直後の文字が全角文字であるスペース」が検索できれば、「4 月 1 日」の3つのスペースをもれなく検出できます。それを可能にするのが「先読み(lookahead)」と「後読み(lookbehind)」です。
マッチしても止まらず先を読む「(?= )」
先読みは「パターン1(?=パターン2)」という形です。先読みでは、まずは「パターン1」にマッチする文字列を検索しますが、それが見つかっても、まだマッチしたことにはなりません。その直後の文字列を「パターン2」と照合し、これもマッチしてはじめて、パターン1のマッチが成功となります。
たとえば、山は「山」ならなんでもマッチしますが、山(?=田)とすると、直後に「田」が続く「山」にのみマッチします。そのため、「山田」の「山」にはマッチしますが「山本」の「山」にはマッチしません。
全角文字と半角文字のあいだにスペースがないパターンは、先読みだけで検索できます。「直後の文字が半角文字である全角文字」と「直後の文字が全角文字である半角文字」を検索すればよいのです。
前回見たように、全角文字は[\p{Lo}\p{Lm}0-9A-Za-z]、半角文字は[\p{Lu}\p{Ll}\p{Lt}0-9-[A-Za-z]]で検索できます。したがって、[\p{Lo}\p{Lm}0-9A-Za-z](?=[\p{Lu}\p{Ll}\p{Lt} 0-9-[A-Za-z]])|[\p{Lu}\p{Ll}\p{Lt}0-9-[A -Za-z]](?=[\p{Lo}\p{Lm}0-9A-Za-z]) とすれば、全角文字と半角文字のあいだにスペースがないパターンをもれなく検索できます。
マッチしたら振り返って後を読む「(?<= )」
一方、後読みは「(?<=パターン2)パターン1」という形です。やはり「パターン1」にマッチする文字列を検索しますが、それが見つかったら、その直前の文字列を「パターン2」と照合します。たとえば(?<=山)田とすると、「山田」の「田」にはマッチしますが「本田」の「田」にはマッチしません。
全角文字と半角文字のあいだにスペースがあるパターンは、「直前の文字が全角文字であり直後の文字が半角文字であるスペース」または「直前の文字が半角文字であり直後の文字が全角文字であるスペース」ですから、先読みと後読みを組み合わせることで検索できます。すなわち、(?<=[\p{Lo}\p{Lm}0-9A-Za-z])\p{Z}+(?=[\p{Lu}\p{Ll}\p{Lt}0-9-[A-Za-z]])|(?<=[\p{Lu}\p{Ll}\p{Lt}0-9-[A-Za-z]])\p{Z}+(?=[\p{Lo}\p{Lm}0-9A-Za-z])という正規表現が、全角文字と半角文字にはさまれたスペースにマッチします。
先読みの否定「(?! )」と後読みの否定「(?<! )」
先読みと後読みの正規表現で「=」を「!」に変えると、否定形になります。つまり、山(?!田)は直後の文字が「田」でない「山」にマッチし、(?<!山)田は直前の文字が「山」でない「田」にマッチします。
これらを用いた実用的な例を2つ紹介しましょう。
まず、本来は全角ハイフン「―」を使うべきところに長音記号「ー」を使ってしまったというエラーを検出してみましょう。このエラーを目で見て探すのは苦行でしかありませんが、直前の文字がカタカナでない長音記号を探せばよいので、正規表現を使えば(?<![ァ-ヴ])ーで簡単に検索できます。
次に、「コンピューター」のように長音記号で終わるカタカナ語を検索してみましょう。「1文字以上のカタカナ+長音記号」で検索すればよいと思うかもしれませんが、それでは「コンピュータ」の「コンピュー」にもマッチしてしまいます。
長音記号で終わるカタカナ語を検索するには、直後の文字がカタカナでない「1文字以上のカタカナ+長音記号」を検索しなければなりません。そこで先読みの出番です。正規表現は [ァ-ヴー]+ー(?![ァ-ヴ])となります。
今回のまとめと次回の予告
今回は、先読み「(?= )」と後読み「(?<= )」およびそれぞれの否定「(?! )」と「(?<! )」を紹介しました。これらはマッチに条件を付加しているとみなせますが、このように、満たされるべき条件を記述するものをアサーション(assertion)と呼ぶことがあります。
さて、これまで、かなり高度な正規表現も含め、さまざまな正規表現を紹介してきましたが、まだ触れていないメタ文字がいくつか残っています。次回はそれらを解説します。
川村インターナショナルの翻訳サービス
川村インターナショナルでは、AIや機械翻訳の活用、プロセスの自動化やデジタル化による翻訳業務効率化ソリューションをご提案します。翻訳支援ツールの導入を検討している、自社の翻訳資産を活用して機械翻訳エンジンをカスタマイズしたい、など翻訳業務の効率化をご検討中の方は、ぜひお気軽にお問い合わせください。
関連記事