4月23日に翻訳勉強会「十人十色」で、正規表現入門セミナーを行いました。その時の講師の一人 高橋さんが、受講者から寄せられたお題を例にして、秀丸エディタによる正規表現の実例と説明をブログ「禿頭帽子屋の独語妄言 side A」で連載されています。
私は、業務ではマイクロソフトワードを使ってそういった処理しているので、どうしてもワードの「ワイルドカード+正規表現」の組合せでの実現方法を考えてしまいます。Twitter で、高橋さんのお題説明に沿ってワードの正規表現説明をしてみようか?とツイートしたら、意外に反響がありましたので、高橋さんのご了解をいただいて「ワード正規表現」を当ブログで説明していきたいと思います。
最初に断っておきますが、私もワードの正規表現を使い始めて、まだ日が浅いです。「それ違うぞ」「こう表現した方がいい」というツッコミを是非お願い致します。
〜〜〜〜
ここでは、私の持つWindows Word 2007とMac Word 2011をベースに説明を進めます。他バージョンの方はごめんなさい。でも、やり方は同じ筈です。
ワード上でこれらの検索・置換を行う上でのお約束として、「ワイルドカードを使用する」をレ点してONにして下さい。
Windows Word 2007: CTRL+H で「検索と置換」ウインドウを出し、「オプション(M)」を押すと「検索オプション」が出ます。そこに「ワイルドカードを使用する」がありますので、レ点を入れてONにしておいて下さい。
Mac Word 2011: shift+command+H で「検索と置換」サイドウインドウを出し、ギアマークを押して「高度な検索と置換」を選択します。「▼」を押すと「検索オプション」が出ますので、そこにある「ワイルドカードを使用する」にレ点を入れてONにします。
〜〜〜〜
今回は、高橋さんのブログの「# 翻訳者のための正規表現~勉強会の解説、その1」のお題内容をワードの正規表現を使ってやってみます。
表記については、高橋さんのブログの記述に従います。
- 「お題」と【解説】の中では半角スペースを△、全角スペースを□で表します。
- 【検索】、【置換】の中では、半角スペースも全角スペースも実際の文字で表しています。
したがって、【検索】【置換】の文字列は、そのままコピペすれば試すことができます。
お題その1
・Page△12 → 12ページ
【検索】
Page ([0-9]{1,})
【置換】
¥1ページ
【解説】
- Page△ ………英語の”Page”と半角スペース
- () ………括弧内の式の結果が、置換語の¥nへ代入されます。()の登場順番に従い ¥1, ¥2 … となります。
- [0-9] ………半角数字
- {1,} ………1回以上の連続出現
{n} もしくは {n,m} と表現されます。{3} で3回連続、{1,} で1回以上連続、{1,5}で1回〜5回の連続…という意味になります。n,m には0(ゼロ)は設定できません。
この場合の「([0-9]{1,})」とは、検索対象は「半角数字が1回以上連続している箇所」で、それを¥1へ代入します。お題の例ですと「12」がこれに該当します。
秀丸エディタの正規表現で、 ¥f (区切り文字)で区切られた前後の式の結果が、それぞれ ¥0, ¥1 へ代入されると習いました。ワードでは半角括弧()内の式の結果が代入されます。()の登場する順番で ¥1, ¥2… と代入されます。秀丸エディタは¥0からでしたが、ワードは ¥1 から始まります。
お題その1の応用
・Page△12 → 12ページ
・Page24 → 24ページ
さて、これがワードでは問題なのです。私の知る限り、秀丸エディタの正規表現にある「?」(0か1回)に該当する表現がないのです(ちなみにワードでは「?」は任意の一文字という意味になります)。従って、上記のお題その1の置換を行い、かつ、以下の置換を行って初めて、この応用問題をクリアできます。
(もし、1文で表現できる方法をご存知の方は、教えて下さい)
きました!きました!読者さんから、こうすれば一行で表現できる!という案が、それを以下に示します。
【検索】
Page([0-9]{1,})
Pag[e ]{1,2}([0-9]{1,})
【置換】
¥1ページ
【解説】
Pag[e△]{1,2} で、Page, Pag△, Page△, Pagee, Pag△e, Pag△△ が対象になります。ここで欲しいのは「Page」と「Page△」ですね。それ以外の「Pag△, Pagee, Pag△e, Pag△△」 が有り得るか?って事ですが、無いと考えていいでしょう。
正規表現は組合せ方を工夫する事で、色々な事ができますが、こういう発想はとても素敵ですよね。参りました(笑)
@trantran93 さん、ありがとうございました。
先のお題その1と違うのは、Pageの後ろにあった半角スペースをなくしただけです。半角スペースがあるのとないのと…という表現ができないので、2段階で置換する形になってしまいます。
例えば、Page△{0,}([0-9]{1,}) なんて記述ができれば良いのですが、上で説明した通り {0,} というゼロ指定が許されていません。(「検索した文字列」に指定したパターン マッチングが正しくありません…というエラーになる)
お題その2
・長いカタカナ語を最初の3文字にしたい
例:「クルーズ・コントロール」を「クルー」に
【検索】
([ァ-ヾ][ァ-ヾー・]{2})[ァ-ヾー・]{1,}
【置換】
¥1
【解説】
- () ………括弧内の式の結果が、置換語の¥nへ代入されます。()の登場順番に従い ¥1, ¥2 … となります。
- [ァ-ヾ] ………1文字目は全角カタカナ(UNICODE)のみ。
- [ァ-ヾー・] ………2文字目以降は長音と中黒あり。
- {2} ………直前の文字が2回繰り返される。
- [ァ-ヾー・] ………長音と中黒を含む全角カタカナ
- {1,} ………直前の文字が1回以上繰り返される。
([ァ-ヾ][ァ-ヾー・]{2})[ァ-ヾー・]{1,} :1文字目が全角カタカナで、2文字と3文字目が長音、中黒、全角カタカナのいずれか、4文字目以降が長音、中黒、全角カタカナのいずれかである文字列が検索され、最初の3文字の文字列が ¥1 へ代入される。
〜〜〜〜〜〜〜
上記のお題その1の応用のようなケースですと、2つの置換作業を行わないと対応できません。こういう作業を一括で行うにはマクロに盛り込んでしまうのが1つの手ですが、検索対象が変わるたびにマクロを書き換えるのも手間が掛かります。
そこで私が使っているのが拙作のGlossaryMatchなんです。上記のケースですと、以下のようなテキスト型の辞書ファイルを作り、全置換で適用すれば、一度に適用できます。
Page ([0-9]{1,}) <TAB> ¥1
Page([0-9]{1,}) <TAB> ¥1
検索対象が変われば記述を変えるだけで対応できます。ちょこちょこ検索対象を変えるなら、辞書ファイルをノートパッド等で開いたままにして、記述を変更→上書き保存→GlossaryMatchで実行…のサイクルを繰り返せば楽です。
以上、ご参考です。