- ベストアンサー
Perlの構文についてわからないところがあります。
こんにちわ。Perlの構文で解らない所があるので教えて下さい。アドレスの識別をする式なのですが、力がなくわからないので教えて下さい。下記の2つです宜しくお願いします。 (1)my$byte=qq{(?:1?$digit?digit | 2[0-4]$digit | 25[0-5])}; (2)my $sub_domain=qq{[$letter$digit] [$letter$digit-]{0,61}[$letter$digit]};
- みんなの回答 (7)
- 専門家の回答
質問者が選んだベストアンサー
キャラクタクラス(=ブラケット=[])内の記号に関して。 最初か最後にあるハイフンは - そのものとして扱われます。 同様に否定のクラスを意味する ^ も先頭以外に置けば ^ そのものとして扱われます。 古いバージョンではどうなってるか確認できませんでしたが、5.005からはこのような仕様になっています。 http://www.kt.rim.or.jp/~kbk/perl5.005/perlre.html#Version_8_Regular_Expressions また . や * や | などもキャラクタクラス内であればエスケープを省略できます。 次は \ に関して。 メタキャラクタの前に置くと、元々あった意味を打ち消しただの文字として扱われます。 逆に英数字の前に置くと、意味を持ったメタキャラクタになる場合があります。 nの前に\を置くと改行になるのと同じです。 mの前に\を置くいても対応するメタキャラクタが無いため\が無視されただのmという文字になります。 ただし、ダブルクォート文字列中(以下qq中)か、 パターン文字列中(以下qr中)かで対応するメタキャラクタは異なります。 例1:\nはqq中、qr中ともに共通して改行を表す 例2:\dはqr中のみ[0-9]という意味でqq中では単なる文字dになる 例3:\bはqq中でバックスペース、qr中で単語境界を表す 殆どの差異は例2のようなものです。 例3のような場合もあります。\bだけだったと思いますが。
その他の回答 (6)
No.3 > [$letter$digit-]はa~zと0~9と-のいずれかにマッチするパターンに展開されると思います。 おそらく作者さんは、この意味で作られていると思いますが、 Perlの正規表現では、[ と ]の間にある - は、範囲を意味する ([0-9]と書くと[0123456789]と同じ意味) ので、エスケープが必要です。 (たぶんエラーになって動きません。perlのバージョンによっては動くかも?) [$letter$degit\\-] *この場合のエスケープは\-ではなく\\-です。 No.4読むまで気づかなかった(^^; q{}とすると、$letterや$degitが展開されないので、qq{}でないとダメですね。
補足
有難うございます。qq{}は解りました、有難うございます!でもまだ少し解らなく迷っております。\はどういう意味で出てきたのか解りません、どれが変化したのですか?あと[-]もよく理解できていません。間を意味するのが末尾に来たときはどう考えたらよいのか解らなくなってしまいました。。解説をまたよろしくお願いします。
- SHOO-3
- ベストアンサー率56% (28/50)
後は正規表現の文法(?)のことなのですが (?:XXXXX) これで、XXXXXの部分に入っているものを括弧でくくったものと判断しますが、普通の括弧でくくったものと違い、$1などで参照できる変数に、パターンマッチ部分が代入されないというものです。変数に代入したくないときに使います。(処理速度がちょっとだけ速くなります) (?:1?$digit?digit|2[0-4]$digit|25[0-5]) 「|」は、「または」という意味です。 この正規表現の文字列が正しいと仮定した場合(多分digitのところが$digitという間違い)は、 一文字目が1個あるいは0個の1から始まり、2文字目が1個、あるいは0個の$digitで表される文字が入り、以降digitと続く文字列にマッチする。 もしくは、1文字目が2から始まり、2文字目が0,1,2,3,4のいずれかであり、3文字目以降が$digitである文字列にマッチする。 もしくは、1文字目が2、2文字目が5、3文字目が0,1,2,3,4,5である文字列にマッチする。 という意味になり、例を挙げると、$digitに4が入っていた場合、 「14digit」「4digit」「1digit」「digit」 「204」「214」「224」「234」「244」 「250」「251」「252」「253」「254」「255」 にマッチします。
お礼
SHOO-3さん、有難う御座います。とても解りやすいご説明で式も面白く感じました。早速URLも拝見しました、とっつき安い表現になっておりとても良いサイトだと思います。本当に有難う御座います。頑張りたいと思いますので今後ともよろしくお願いします。
- yuuki0229
- ベストアンサー率70% (33/47)
No.3に一部間違いがありましたので訂正します。 (9行目)qq{}の時点で\dを用いると単なる文字dになってしまうため、 qq{}内の\dを\\dや[0-9]とするか、qq自体をqにする必要がありました。 失礼しました。
- yuuki0229
- ベストアンサー率70% (33/47)
どちらも正規表現を文字列的として組み立てています。 $digitとありますが、(2)ではキャラクタクラスの中で展開されているため "0-9"や"012345678"といった文字列が格納されてると推測できますが (1)では直接パターンとして展開されているため "[0-9]"といった文字列でなければまともな判別は行えないでしょう。 $digit(と転記ミスと思われるdigit)を等価であろう\dに置き換えておきます my $byte = qq{(?:1?\d?\d|2[0-4]\d|25[0-5])}; これは0~255までの整数とマッチします。 厳密には"00"などもマッチしてしまいますが。 4つ繰り返してIPアドレスの判別などの用途が推測されます。 [$letter$digit]はa~zと0~9のいずれか [$letter$digit-]はa~zと0~9と-のいずれかにマッチするパターンに展開されると思います。 大文字を入れるかどうかはiオプションで決められるためここで省略します。 それを置き換えておきます。 my $sub_domain = qq{[a-z0-9][a-z0-9-]{0,61}[a-z0-9]}; これは「2~63文字のアルファベットで先頭と末尾以外なら"-"も使ってもいい」といった正規表現になります。 なお、qq{ }中(つまりパターン中)に改行を含むのは基本的にまずいです。
補足
有難う御座います。(2)の方は素晴らしいアドバイスでとても参考になりました。(1)はまだ理解できていませんので今ひとつ御付合いご指導下さい。my $byte = qq{(?:1?\d?\d|2[0-4]\d|25[0-5])}; ここの部分で本当に基礎の所からわからないのですが、?:最初のはパターンマッチで以降の?は直前のパターンの繰り返しということでしょうか・あと25[]の[]前の数字の意味がわかりません。またお教え下さい、宜しくお願いします。それとyuuki0229さんの次のメッセージ読ませて頂きました。有難う御座います。
- SHOO-3
- ベストアンサー率56% (28/50)
見た感じ、おそらく正規表現のための文字列を、qq{}で囲まれた部分で、文字列として$byteや$sub_domainに代入しているのではないでしょうか。 ちなみに、qq{}は、囲まれた部分を"で囲まれた文字列と同等に解釈します。 最初のほうは、 my$byte="(?:1?$digit?digit|2[0-4]$digit|25[0-5])"; とたぶん同等。$digitには $digit="0123456789"; というかんじに、数字が代入されていると予想。
補足
有難うございます。正規表現の?:なのですね。$digitと|とその他の箇所はどこで区切るのかが解りません。これをお読みになったらお返事ください。また、宜しくお願いします。
- agharta
- ベストアンサー率52% (54/103)
$letter $digit に何が入っているのでしょうか?!
お礼
ご解答有難うございました。私に考える機会を与えて下さり、それもいいアドバイスと思いました、本当にですよ。またこちらで質問をすると思いますがその時は宜しくお願いします。
お礼
遅くなって済みません。ご説明有難う御座います。サイトの方も見てみました。詳しく書かれていて、[-]のことも出ていますね。参考に今後もさせて頂きたいと思い内容をファイルしました。qrとqqの中での意味が違うということ、初めて知りました。yuuki0229さんをはじめ皆様のおかげで本当に助かりました、これでこの質問も終えることが出来ます。最後のアドバイス大変参考になりました、有難う御座います。