年月日の表記を考える

公式文書を作成する際に欠かせないのが、その文書の作成日時をあらわす年月日。しかし、その表記は国々によって異なります。例えばアメリカでは「01/12/2009」と「月/日/年」の順番で、イギリスでは「12/01/2009」と「日/月/年」の順番。そして日本はいうまでもなく「2009/01/12」と「年/月/日」の順番です。そもそも、この表記方法自体がわかりにくく、年を2桁にしますと、イギリスとアメリカは区別が不可能になってしまいます。

そのため海外では、「January 12, 2009」と月を英単語表記にすることで見分けやすくしています。蛇足ですが前述のようにカンマで日と年を区切るのがアメリカ式、「12 January 2008」とカンマを使わないのがイギリス式だとか。このように世界レベルで見ても異なる表記方法ですが、日本国内だけに目を向けても「2009年01月12日」「2009.01.12」「2009-01-12」と区切りに用いる単語が異なることもしばしば。今回はこの表記を統一する正規表現にチャレンジしてみましょう。

年月日のパターンを考える

まず、対象なる年月日パターンを考えてみます。区切りが漢字であれば「{数字}年{数字}月{数字}日」、スラッシュなどの記号であれば「{数字}/{数字}/{数字}」などが一般的でしょう。前者を対象にした正規表現を考えると、「[0-9]+年[0-9]+月[0-9]+日」など、直前の文字が1回以上繰り返すことを意味する「+」を使ってしまいがちですが、このままでは「20000000000年」といった、あり得ない数字にもマッチしてしまいます。これでは正しい正規表現とは言えません(図1~2)。

図1 検索ダイアログを開き、「検索」に「[0-9]+年[0-9]+月[0-9]+日」と入力して、[上検索]もしくは[下検索]ボタンをクリックしますと、漢字表記の年月日にマッチします

図2 図1と同じ正規表現を使用しますと、ご覧のとおりあり得ない数字にもマッチしてしまいます。これは、直前の文字が1回以上繰り返すことを意味する「+」を使っているため

少々煩雑ですが、今度は「[0-9][0-9][0-9][0-9]年[0-9][0-9]月[0-9][0-9]日」としてみましょう。実はこの正規表現も問題が発生し、「20000000000年」といった誤表記でも下4桁にマッチしてしまいます。実は文字列の先頭を意味するキャレットを加えることで、誤表記を除外できますが、文書に挿入する日付が必ず行頭にあるとは限らないため、この方法は使用できません(図3)。

図3 検索ダイアログを開き、「検索」に「[0-9][0-9][0-9][0-9]年[0-9][0-9]月[0-9][0-9]日」と入力して、[上検索]もしくは[下検索]ボタンをクリックします。漢字表記の年月日にマッチしますが、誤った表記の年月日にもマッチしてしまいます

5桁以上にマッチさせない

そこで、5桁以上の数値をピックアップさせないため、前方不一致指定を使用しましょう。また、年表記が「2009」や「09」、月表記も「01」や「1」に対応させるため、パターンの繰り返し回数指定も併用します。前者は前方部分が特定のパターンにマッチしないように条件付けるもので、5桁以上の数値を除外させるために、「(?<![0-9])」を加えました。後者は特定の正規表現パターンが、x回以上、y回以下出てくる文字列にマッチするため、年は2回以上4回以下で「{2,4}」、月日は1回以上2回以下で「{1,2}」となります。末尾に行末を意味する「$」を加えた正規表現「(?<![0-9])[0-9]{2,4}年[0-9]{1,2}月[0-9]{1,2}日$」を用いることで、ひとまず完成です(図4)。

図4 検索ダイアログを開き、「検索」に「(?<![0-9])[0-9]{1,4}年[0-9]{1,2}月[0-9]{1,2}日$」と入力して、[上検索]もしくは[下検索]ボタンをクリックします。これで誤った表記にはマッチしなくなりました

区切り文字をブラケットで囲む

次は異なる区切り文字を含めるようにしましょう。こちらは比較的簡単で、各区切り文字をブラケットで囲めばOKです。今回対象とするのは「/」「-」「.」ですので、「[\/-.年]+」「[\/-.月]+」「[\/-.日]?」と変更を加え、「(?<![0-9])[0-9]{1,4}[\/-.年]+[0-9]{1,2}[\/-.月]+[0-9]{1,2}[\/-.日]?$」としましょう。ちなみに最後だけ「?」を用いるのは、漢字以外の区切り文字がないためです(図5)。

図5 検索ダイアログを開き、「検索」に「(?<![0-9])[0-9]{1,4}[\/\-\.年]+[0-9]{1,2}[\/\-\.月]+[0-9]{1,2}[\/\-\.日]?$」と入力して、[上検索]もしくは[下検索]ボタンをクリックします。これで半角記号を用いた年月日もマッチするようになりました

同様の手順で全角数字も含めてみましょう。こちらは各数字をあらわす「[0-9]」が変更対象となります。単純に全角数字の範囲を加えるだけですので、各数値を対象にしたキャレットを「[0-90-9]」と書き換えましょう。また区切り文字も全角をサポートさせるため「/?.」も加えますと、結果は「(?<![0-90-9])[0-90-9]{1,4}[\/-./?.年]+[0-90-9]{1,2}[\/-./?.月]+[0-90-9]{1,2}[\/-./?.日]?$」となります。これで全角数字を用いた年月日もマッチ対象になりました(図6)。

図6 検索ダイアログを開き、「検索」に「(?<![0-90-9])[0-90-9]{1,4}[\/\-\./?.年]+[0-90-9]{1,2}[\/\-\./?.月]+[0-90-9]{1,2}[\/\-\./?.日]?$」と入力して、[上検索]もしくは[下検索]ボタンをクリックします。これで全角数字や全角記号を用いた年月日もマッチするようになりました

「年月日」に統一する

最後に年月日の区切り文字を「年月日」に統一する正規表現にチャレンジしましょう。ここまでご覧になった方には簡単です。ポイントは置換後にも残さなければならない数字部分をパーレンで囲むだけ。置換時はタグ付き正規表現で取り出せば、簡単に文字列置換が可能になります。検索対象となる正規表現は「(?<![0-90-9])([0-90-9]{1,4})[\/-./?.年]+([0-90-9]{1,2})[\/-./?.月]+([0-90-9]{1,2})[\/-./?.日]?$」。置換対象となる文字列は「年月日」に置換するため、「\1年\2月\3日」とすればすべての区切り文字が統一されます(図7)。

図7 置換ダイアログを開いて正規表現を入力し、[全置換]ボタンをクリックすれと

一括して年月日の区切りが漢字に統一されます

区切り文字を全角文字にするときは、そのまま置き換えれば置換可能ですが、半角文字を使用するときは注意が必要です。例えば半角のピリオドはそのままメタ文字として認識されてしまうため、「\1.\2.\3」とメタ文字を文字として指定する「\」を直前に加えてください。

正規表現

 検索文字列:(?<![0-90-9])([0-90-9]{1,4})[\/\-\./−.年]+([0-90-9]{1,2})[\/\-\./−.月]+([0-90-9]{1,2})[\/\-\./−.日]?$
 置換文字列:\1年\2月\3日

阿久津良和(Cactus)