perlで次の条件はどういう意味になりますか?

if (shift =~ /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/) { $starttime = Time::Local::timelocal($6,$5,$4,$3,$2-1,$1); }

10進数で日付フォーマットか?という意味合いで使われているようなのですが、解釈のコツがつかめません。

回答の条件
  • URL必須
  • 1人3回まで
  • 登録:
  • 終了:2007/02/19 19:50:50
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答6件)

id:openseed No.1

回答回数51ベストアンサー獲得回数6

ポイント19pt

shift の戻り値は、暗黙で、

my $s = shift(@_);

とされたときの、$s の値と同じです。

// 厳密にはちょっと違いますが。

※ ファンクションの先頭行で実行されていますでしょうか? その場合は、呼び出し元の第一引数になります。


正規表現の説明は難しいですね。

まず、整数([0-9])で14桁であるとき、先頭の4文字を$1 で、次の2文字を$2 で ・・・ 参照できるようになります。

仮に、shift の値が "20060213123456" とすると、

$1 = 56

$2 = 34

$3 = 12

$4 = 13

$5 = 02

$6 = 2006

になります。

なので、日付のフォーマットチェックは、行われず、数値14桁である条件だけで、1970年1月1日0時0分0秒からの経過秒に変換しようとしています。

※ たとえば、99999999999999 が入力されても、$starttime には値が代入されると思います。


説明になっていないかもしれませんが、参考まで。

※ URLは「shift, timelocal」で検索した1件目です。

timelocal:

http://cocohome.hp.infoseek.co.jp/cocohome/l_nisukeisan.html

shift:

http://www.rfs.jp/sb/perl/05/shift.html

id:P-mako

ご回答ありがとうございます。

非常にわかりやすい説明でした。

~(チルダ)の意味ってなんでしょうか?

Cや類似言語では否定だったと思いますし、

 +=や-=、^=(XOR+イコール)、もっといえば

~=(NOT+イコール)ならわかる気がするんですが、

=~ってどういう意味なんでしょう?

2007/02/14 10:39:41
id:k-onishi No.2

回答回数23ベストアンサー獲得回数1

ポイント19pt

shift(引数の最初のひとつを取り出したもの)に、

12桁の数字(\d)が含まれていれば、

最初の4桁とその後の2桁5つに分けて($1~$6に代入)、

Time::Local::timelocalの引数とし、

結果を $starttime に代入する

ということですね。


たぶん引数が年月日時分秒の12桁の数字になっていれば、

その値を内部時間に変換し $starttime に入力するものと思います。

http://q.hatena.ne.jp/1171356544

id:P-mako

ご回答ありがとうございました。

2007/02/14 10:39:01
id:huruyosi No.3

回答回数30ベストアンサー獲得回数3

ポイント19pt

http://cocohome.hp.infoseek.co.jp/perl_ref/localtime.html

Time::Local::timelocalの説明はこちらをご参照ください。


正規表現の「\d」は数字を表し括弧でグループ化して、$1~$6の部分で取り出しています。これを踏まえると

(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)

4文字の数字 -> $1

2文字の数字 -> $2

2文字の数字 -> $3

2文字の数字 -> $4

2文字の数字 -> $5

2文字の数字 -> $6

と解釈できます。たとえば変数shift の値が「2007年1月13日 21時22分18秒」を表す「20070113212218」だとすると

2007 -> $1

01 -> $2

13 -> $3

21 -> $4

22 -> $5

18 -> $6

になります。


文字列を年月日、時分秒に分解した後に時間を表すクラスに変換しています。

id:P-mako

ご回答ありがとうございました。

2007/02/14 10:39:03
id:nev No.4

回答回数77ベストアンサー獲得回数4

ポイント19pt

shift は shift @_ の意味なので、

その箇所がサブルーチンの一部であれば、先頭の引数を返します。

$1,$2 ... $6 は、正規表現内のカッコに相当する部分が入ります。

YYYYMMDDhhmmss 形式の 10 進数の文字列が渡されたとしたら、

YYYY の部分が $1 に、

MM の部分が $2 に、

...

ss の部分が $6 に、それぞれ入ることになります。

http://q.hatena.ne.jp/1171356544


id:P-mako

ご回答ありがとうございました。

2007/02/14 10:39:06
id:openseed No.5

回答回数51ベストアンサー獲得回数6

ポイント18pt

すみません。逆でした。

以下が正しいです。

shift = 20060213123456; のとき、
$0 = 20060213123456
$1 = 2006
$2 = 02
$3 = 13
$4 = 12
$5 = 34
$6 = 56

nev さんのように、 YYYYMMDDhhssmm と表現するほうが、分かりやすいかもしれませんね。

=~ についてですが・・・、詳しくは答えられませんが、正規表現など、置換やパターンマッチングを行うときの演算子として利用しています。

http://perldoc.jp/docs/perl/5.6.1/perlop.pod

Binding Operators の項目


基本的に、= が後に来るのは、演算後の代入だと認識しています。

※ =~ で置換もできるから、必ずしも断言できないのですが・・・

参考になれば幸いです。

id:P-mako

> 基本的に、= が後に来るのは、演算後の代入だと認識しています。

 ++$i

とかと同じってことですね。

 +=も同様に=+があったんでしたっけ・・・

ありがとうございました。

でも、いまひとつ解釈のコツとしてはクリアになっていないです・・・

たとえば、

$i++や$i+=1

なら、

$i=$i+1

がわかりやすくて、厳密(?)な記述になると思います。

では、質問の条件式は、どうなるんでしょう?(という質問文のほうが良かったかも知れないですね。)

2007/02/14 20:18:39
id:k-onishi No.6

回答回数23ベストアンサー獲得回数1

ポイント16pt

もう解決しているかもしれませんが。


> =~ってどういう意味なんでしょう?

左辺を右辺のパターンで マッチ、置換、変換 を行う演算子です。

http://homepage2.nifty.com/sak/w_sak3/doc/sysbrd/pe_k08.htm


=~ の後の演算子が m, s, tr の場合に それぞれ マッチ、置換、変換 の演算が行われます。省略すると m(マッチ) となります。


shift =~ /(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)/

この場合は m が省略されていてマッチになります。

つまり shift の内容が /.../ で囲まれているパターンにマッチすれば true を返します。

\d は 数字[0-9] を表すメタ文字です。

たとえば \d\d\d\d は4桁の数字にマッチします。

これを ( ) で囲うと マッチした文字列が順に $1, $2, $3... に代入されていきます。

(\d\d\d\d)(\d\d)(\d\d)(\d\d)(\d\d)(\d\d)

この場合では、最初に現れた4桁の数字が $1 に、次の2桁の数字が $2 にというように代入され、そのあとの式で利用することができるようになります。

id:P-mako

わかりやすい説明ありがとうございました。

2007/02/19 19:48:42

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません