フォーマットを順番に一致させてみてください。以下の正規表現は、許可されているセパレーター(、、、または)のいずれかに一致し、/
後方.
参照(または)-
を介して同じセパレーターを必要とします。それ以外の場合は、パターンに6つの選択肢を作成するために、3つの可能なセパレーターに1年の2つの可能な位置を掛けたものがあります。\2
\3
#! /usr/bin/env perl
use strict;
use warnings;
#array values may vary in every run
my @dates = ("Mon 11/20/2012","2012.11.20","20-11-2012");
my $date_pattern = qr<
\b # begin on word boundary
(
(?: [0-9][0-9] ([-/.]) [0-9][0-9] \2 [0-9][0-9][0-9][0-9])
| (?: [0-9][0-9][0-9][0-9] ([-/.]) [0-9][0-9] \3 [0-9][0-9])
)
\b # end on word boundary
>x;
foreach my $date (@dates) {
if (my($match) = $date =~ /$date_pattern/) {
print "Date: $match\n";
}
}
出力:
日付:11/20/2012
日付:2012.11.20
日付:2012年11月20日
上記のコードを最初に試したとき\2
、YYYY-MM-DDの代替案があったはず\3
でしたが、一致しませんでした。括弧のカウントを省くために、バージョン5.10.0では名前付きキャプチャバッファが追加されました。
パターン内のキャプチャ括弧に名前を付け、キャプチャされたコンテンツを名前で参照できるようになりました。命名構文は(?<NAME>....)
です。構文を使用して、名前付きバッファーへの逆参照を行うことができ\k<NAME>
ます。コードでは、新しい魔法のハッシュが使用され、キャプチャバッファの内容%+
に%-
アクセスできます。
この便利な機能を使用すると、上記のコードは次のようになります。
#! /usr/bin/env perl
use 5.10.0; # named capture buffers
use strict;
use warnings;
#array values may vary in every run
my @dates = ("Mon 11/20/2012","2012.11.20","20-11-2012");
my $date_pattern = qr!
\b # begin on word boundary
(?<date>
(?: [0-9][0-9] (?<sep>[-/.]) [0-9][0-9] \k{sep} [0-9][0-9][0-9][0-9])
| (?: [0-9][0-9][0-9][0-9] (?<sep>[-/.]) [0-9][0-9] \k{sep} [0-9][0-9])
)
\b # end on word boundary
!x;
foreach my $date (@dates) {
if ($date =~ /$date_pattern/) {
print "Date: $+{date}\n";
}
}
同じ出力を生成します。
上記のコードにはまだ多くの繰り返しが含まれています。名前付きキャプチャと組み合わせた特殊なケースを使用(DEFINE)
すると、パターンをより適切にすることができます。
#! /usr/bin/env perl
use 5.10.0;
use strict;
use warnings;
#array values may vary in every run
my @dates = ("Mon 11/20/2012","2012.11.20","20-11-2012");
my $date_pattern = qr!
\b (?<date> (?&YMD) | (?&DMY)) \b
(?(DEFINE)
(?<SEP> [-/.])
(?<YYYY> [0-9][0-9][0-9][0-9])
(?<MM> [0-9][0-9])
(?<DD> [0-9][0-9])
(?<YMD> (?&YYYY) (?<sep>(?&SEP)) (?&MM) \k<sep> (?&DD))
(?<DMY> (?&DD) (?<sep>(?&SEP)) (?&MM) \k<sep> (?&YYYY))
)
!x;
foreach my $date (@dates) {
if ($date =~ /$date_pattern/) {
print "Date: $+{date}\n";
}
}
はい、DMYという名前のサブパターンもMDY形式の日付と一致します。今のところそれで十分です、そしてあなたはそれを必要としないでしょう。