こんにちは、デジタル事業本部の藤田です。
今回は、日付(「mm月dd日」形式)を正規表現で検索する方法を考えてみました。
InDesign ストーリーテキスト内の「○月●日」という日付文字列を指定する正規表現スタイル作成が目的です。
以下の表は日付一覧マトリクスです。横が 1〜12月の月名 、縦が 1〜31日の日名 です。便宜上、実際には存在しない日付も記入されています。
● とりあえず数字と日付で検索させる
・1桁の数字
単純に 数字+月+数字+日 で検索するのであれば
ですが、これでは1桁の数字しか検索できません。
・2桁の数字
上記の数字文字列を1桁以上2桁までの数字として検索するのであれば
ですが、これだと2桁までの数字がなんでもマッチしてしまいます。
例えば、「2月30日」、「16月」、「99日」、「0月0日」など存在しない日付にもマッチしてしまいます。
日付を検索するなら、1月〜12月各月のしかるべき日数を指定する必要があります。
● ニシムクサムライ
月ごとの日数を判別する方法で「ニシムクサムライ」という語呂合わせがあります。
漢字で書くと「二四六九士」、つまり2・4・6・9・11月は他の月と日数が違う(31日ではない)ことを判別する語呂合わせです。「二四六九」という当て字も通販番組の電話番号みたいですがまあ理解できます。ただ「士」という字を分解して「十一」、サムライが11に変換されるというのはいささか強引な気が…語呂合わせの世界ではフレキシブルな解釈が必要です。
● 1か月の日数が31日の月
1・3・5・7・8・10・12月は1か月の日数が31日です。
・31日の月編
1・3・5・7・8は1桁数字なので角括弧 [...] で囲むことでそれぞれの数字いずれかにマッチする1文字が組み立てられます。
さらに、2桁の数字文字列 10・12 と丸括弧 (…) でくくってグループ化し、それぞれの単語を縦棒 | で区切ることでマッチする文字列が組み立てられます。
・31日の日編
1から31という数字をマッチさせるので [1-31] にすればいいかと思ってしまいがちですがそうではありません(※「1・2・3」いずれかの1文字しかマッチしません)。日付を文字としてパターン分解する必要があります。
日付 | 正規表現 | 意味 |
---|---|---|
1から9まで | [1-9] | 一の位が1から9 |
10から29まで | [12][0-9] | 十の位が1または2で、一の位が0から9 |
30と31 | 3[01] | 十の位が3で、一の位が0または1 |
これらを丸括弧 (…) でくくってグループ化し、それぞれの単語を縦棒 | で区切ることで1から31の日付文字列にマッチする文字列が組み立てられます。
上記の月日の正規表現を合わせることで1か月の日数が31日の月を検索する正規表現ができます。その前に、少し工夫して日付の前の文字が数字ではない条件を付け加えます。
否定後読みの条件です。これを前に付け加えます。
これで、1か月の日数が31日の月の日付を検索する正規表現ができました!
● 1か月の日数が30日の月
「ニシムクサムライ」のうち4・6・9・11月は1か月の日数が30日です。
・30日の月編
4・6・9は1桁数字なので角括弧 [...] で囲むことでそれぞれの数字いずれかにマッチする1文字が組み立てられます。
さらに、11 も丸括弧 (…) でくくってグループ化し、それぞれの単語を縦棒 | で区切ることでマッチする文字列が組み立てられます。
・30日の日編
こちらも日付を文字としてパターン分解する必要がありますが、1か月の日数が31日の月でつくったパターンを改変するだけです。
日付 | 正規表現 | 意味 |
---|---|---|
1から9まで | [1-9] | 一の位が1から9 |
10から29まで | [12][0-9] | 十の位が1または2で、一の位が0から9 |
30 | 30 | 十の位が3で、一の位が0 |
これらを丸括弧 (…) でくくってグループ化し、それぞれの単語を縦棒 | で区切ることで1から30の日付文字列にマッチする文字列が組み立てられます。
上記の月日の正規表現を合わせることで1か月の日数が31日の月を検索する正規表現ができます。こちらも、日付の前の文字が数字ではない否定後読みの条件を付け加えます。
これで、1か月の日数が30日の月の日付を検索する正規表現ができました!
● 2月
2月は1か月の日数が28日ですが、うるう年も考慮して29日で組み立ててみます。
・2月の月編
こちらはそのままです。
・2月の日編
2月も日付を文字としてパターン分解する必要がありますが、上で作成した31日や30日の日パターンから30以降を取るだけです。
日付 | 正規表現 | 意味 |
---|---|---|
1から9まで | [1-9] | 一の位が1から9 |
10から29まで | [12][0-9] | 十の位が1または2で、一の位が0から9 |
これらを丸括弧 (…) でくくってグループ化し、それぞれの単語を縦棒 | で区切ることで1から29の日付文字列にマッチする文字列が組み立てられます。
上記の月日の正規表現を合わせることで2月の日付を検索する正規表現ができます。こちらも、日付の前の文字が数字ではない否定後読みの条件を付け加えます。
これで、2月の日付を検索する正規表現ができました!
● すべてを結合
あとは、これら3つを丸括弧 (…) でくくってグループ化し、それぞれの単語を縦棒 | で区切ることで日付文字列にマッチする文字列が組み立てられます。
これで日付を検索する正規表現ができました!
実際はこんなにややこしいことはしないかもしれませんが、日付表記は普遍的なものなので汎用性はあるかもしれません?