-5

2012 年 4 月 9 日は、次のいずれかの方法で記述できます。

4912
4/9/12
4-9-12
4 9 12
04-9-12
04-09-12
4 9 2012
4 09 2012
(I think you get the point)

よくわからない人のために、ルールは次のとおりです。

1. Dates may or may not have ` `, `-` or `/` between them
2. The year can be written as 2 digits (assumed to be dates in the range of [2000, 2099] inclusive) or 4 digits
3. One digit month/days may or may not have leading zeroes.

これを解決して日付を 04/09/12 にフォーマットするにはどうすればよいでしょうか?

12112 が 12/1/12 または 1/21/12 のように、日付があいまいになる可能性があることはわかっていますが、可能な限り小さい月を想定しています。

4

2 に答える 2

2

これは実際には正規表現が得意とすることです。仮定を立て、それを前に進め、必要に応じて後戻りして一致を成功させます。

s{
    \A 
    ( 1[0-2] | 0?[1-9] )
    [-/ ]?
    ( 3[01] | [12][0-9] | 0?[1-9] )
    [-/ ]?
    ( (?: [0-9]{2} ){1,2} )
    \z
 }
 {
    sprintf '%02u/%02u/%04u', $1, $2, ( length $3 == 4 ? $3 : 2000+$3 )
 }xe;

現在の範囲チェックは、月の値によって決定されるわけではありませんが、あいまいなケース (適切な日付がある場合) から適切な日付を選択するのに十分なはずです。

最初に 2 桁の月と日を試すことが重要であることに注意してください。それ以外の場合、111111 は 1-1-1111 になり、おそらく意図された 11-11-11 ではありません。ただし、これは 11111 が 1-11-11 ではなく 11-1-11 を好むことを意味します。

有効な月日チェックが必要な場合は、再フォーマット後に実行する必要があります。

ノート:

s{}{}/ の代わりに中括弧を使用して正規表現の部分を区切り、/ をエスケープする必要がないようにする置換です。また、ペアの区切り記号を使用すると、パターンと置換部分の両方を開閉できるため、見栄えがします。

\A一致する文字列の先頭に一致します。\z末尾に一致します。 ^これに$よく使用されますが、場合によってはわずかに異なる意味を持つことがあります。これらは常に 1 つのことしか意味しないので、私はこれらを好みます。

末尾の x フラグは、これが拡張された正規表現であり、余分な空白や無視されるコメントを含めることができるため、読みやすくなっています。(文字クラス内の空白は無視されません。) e フラグは、置換部分が文字列ではなく、実行するコードであることを示します。

'%02u/%02u/%02u'値を取得して特定の方法でフォーマットするために使用されるprintf形式です。http://perldoc.perl.org/functions/sprintf.htmlを参照してください。

于 2013-03-13T20:54:32.253 に答える
1

インストール日::Calc

ubuntu の場合 libdate-calc-perl

これは、これらすべての日付 ( 4912, 4 9 2012, 4 09 2012 を除く) を読み取り、共通の形式で出力できるはずです。

于 2013-03-13T20:17:41.607 に答える