Perlについて質問です。


すいませんが、下の命令についてどなたかわかりやすい説明をして下さる方はいらっしゃらないでしょうか?

1.
if(-f "$dir/$get"){ 処理A }

2.
($ext = $get) =~ s/^.+\.([^\.]+)$/$1/;

大変身勝手な質問ですいませんが、よろしくお願いします。少し高めのポイントをご提供します(^^

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2006/08/31 14:43:15
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:Iwa No.4

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

ポイント200pt

どこかで見たことがあるかと思ったらこれは以前私が投稿したやつですかね。

まあそれは置いといて。

まずは簡単なものから

$hoge =~ s/A/B/;

こうすると、変数$hogeの中の文字列「A」が「B」に置き換わります。

但し、これだけだとはじめのAだけがBに置き換わります。

つまり、

「ABCABC」

をこれに通すと

「BBCABC」

になります。

全ての「A」を「B」に変えたければオプションgを付けて

$hoge =~ s/A/B/g;

とします。

さて、これだけだと大文字のAだけが大文字のBに置き換わります。

つまりaはBには変わりません。

大文字小文字を区別せず、Aとaの両方をBにしたければオプションiを付けて

$hoge =~ s/A/B/i;

とします。

先ほどのオプションgと合わせれば

$hoge =~ s/A/B/ig; または $hoge =~ s/A/B/gi;

と書けます。

通常、

$hoge =~ s/A/B/;

このままではAがBになってしまいますが、中には元のAの時のものも残したい場合もあります。

そういうときに手っ取り早い方法は、これに掛ける前にコピーしておくことです。

つまり、

$copy = $hoge;

$hoge =~ s/A/B/;

とすれば、$copyにはAをBに変える前のAの時のものが残ります。

が、

($copy = $hoge) =~ s/A/B/;

と書いた場合は、$copyはAがBに変わったもの、$hogeに変わる前のAのときのものが残ります。

正規表現では特殊文字が使えます。

. は改行文字(\x0A \x0D)を除く任意の1字(1バイト)

* は直前のパターンの0回以上の繰り返し

+ は直前のパターンの1回以上の繰り返し

? は直前のパターンが0回または1回現れる

^ は文字列の先頭([]文字クラスの中では「以外」の動作として使います)

$ は文字列の最後

() はパターンのグループ化

[] は文字クラス(A以外としたいとき、[^A]とします)

\ は右隣のメタ文字(特殊文字)を普通の文字として扱う(エスケープ)

↑はほんの一部ですがとりあえずこれだけ。

で、

($ext = $get) =~ s/^.+\.([^\.]+)$/$1/;

を上記の説明に当てはめると

^.+ は、「先頭が1字以上の文字列で始まる」

\. は「文字としての.がひとつ」

[^\.]+ は「文字.以外が1字以上」

([^\.]+) は「↑を囲ってグループ化(つまりこれにマッチしたものが特殊変数$1に入ります。もし、()を複数使っている場合は$1、$2・・・と増えていきます)」

$ は文字列の最後になります。

でこれを

$1で置き換えます。

この場合は([^\.]+)の中身[^\.]+にマッチしたものに置き換わります。

id:zachouR

重ね重ねありがとうございます。

本当に助かりました、また何かありましたら、ぜひよろしくお願いいたします。

頭の下がる重いです、、、m(_ _)m

2006/08/31 14:40:32

その他の回答3件)

id:ootatmt No.1

回答回数1307ベストアンサー獲得回数65

ポイント100pt

1.

-f $dir/$get は、$dir/$get(たぶんディレクトリ名+ファイル名)というファイルがあるかどうかを確認する演算子です。

http://flex.ee.uec.ac.jp/texi/perl/perl_22.html

つまり $dir/$get が存在すれば 処理A を行う ということ。


2.

$ext = $get

$get(ファイル名)を $ext に代入


s/^.+\.([^\.]+)$/$1/

そのファイル名の "." 以下の部分(つまり拡張子)だけを取り出す。


つまり、$ext には $get(ファイル名)の拡張子が入ります。

id:zachouR

$dir/$get はわかりました!ありがとうございます。

s/^.+\.([^\.]+)$/$1/ も最終的な結果と意味は感覚的にわかるのですが、記号一つ一つについて解説して頂けないでしょうか?

すいませんが、よろしくお願いいたします。

2006/08/31 13:38:08
id:antipattern No.2

回答回数125ベストアンサー獲得回数12

ポイント100pt

変数名からの推測も入りますがご容赦ください.

1)

$dirがディレクトリー名,$getがファイル名だと思います。

これは,$dirディレクトリーに存在するファイル$getが,通常ファイルか否かを調べるif文です。

$dir = "D:\";

$get = "temp.txt";

であったときに,

$dir\$get は "D:\temp.txt";になりますので。

"-f"は通常ファイルか否かをチェックするファイル演算子です。

http://espion.just-size.jp/archives/03/141103545.html

2)

$extは拡張子,$getは1)と同じくファイル名だと思います。

この処理は$extに一旦$getを代入し,その中から"."以降の部分だけを正規表現によって取り出す処理です。

右辺の s/.../.../ は,左側の/.../を右側の/.../の"..."部分に変換する場合の書き方で,右側に記述されている$1というのは,左側の()で囲まれている部分になります。

正規表現に関する詳しい説明は省略させていただきますが,左側の文字列 ^.+\.([^\.]+)$ が意味しているのは,

「文字列の先頭(^)から,何らかの文字が1つ以上続き(.+),その後にドットが存在し,(\.),その後にドット以外の文字列が続いている([^\.]+)ということです。

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

正規表現に関してはちょっと説明が難しいので,もし詳しくお知りになりたいのであれば専門のサイトを確認されることをお勧めします。

id:zachouR

わかりやすい解説ありがとうございます。

正規表現は勉強しているのですが、なかなか難しいです(^^;

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

2006/08/31 13:50:12
id:ootatmt No.3

回答回数1307ベストアンサー獲得回数65

ポイント100pt

s/^.+\.([^\.]+)$/$1/

まず、s// は文字列の置換ですね。ここはいいですよね?

^ は文字列の先頭にマッチします。

.+ は任意の文字列の1回以上繰り返しです。

\. は"."にマッチします。.はそのままでは任意の文字をあらわすので、\でエスケープしています。

(  )はマッチした文字列を保持します($1に代入)

[^\.]+ は \. が"." をあらわし、^ は「それ以外」をあらわしています。

つまり"."以外の文字です。その後の + が1回以上の繰り返しですから、. 以外の文字の繰り返しを表しています。

$ は文字列の終わりにマッチします。

つまりこの前半の部分は、"."以外の文字列が続いて"."があって"."以外文字が続くときに、"."以降の文字を $1 に代入するということです。

後半が $1 になっていますので、最初の文字列(ファイル名)を"."以降の文字列(拡張子)に置換しています。

id:zachouR

正規表現は、わかりかけてきたところですが、なかなか難しいです、、、(;;

親切にありがとうございました!

2006/08/31 13:59:47
id:Iwa No.4

回答回数120ベストアンサー獲得回数6ここでベストアンサー

ポイント200pt

どこかで見たことがあるかと思ったらこれは以前私が投稿したやつですかね。

まあそれは置いといて。

まずは簡単なものから

$hoge =~ s/A/B/;

こうすると、変数$hogeの中の文字列「A」が「B」に置き換わります。

但し、これだけだとはじめのAだけがBに置き換わります。

つまり、

「ABCABC」

をこれに通すと

「BBCABC」

になります。

全ての「A」を「B」に変えたければオプションgを付けて

$hoge =~ s/A/B/g;

とします。

さて、これだけだと大文字のAだけが大文字のBに置き換わります。

つまりaはBには変わりません。

大文字小文字を区別せず、Aとaの両方をBにしたければオプションiを付けて

$hoge =~ s/A/B/i;

とします。

先ほどのオプションgと合わせれば

$hoge =~ s/A/B/ig; または $hoge =~ s/A/B/gi;

と書けます。

通常、

$hoge =~ s/A/B/;

このままではAがBになってしまいますが、中には元のAの時のものも残したい場合もあります。

そういうときに手っ取り早い方法は、これに掛ける前にコピーしておくことです。

つまり、

$copy = $hoge;

$hoge =~ s/A/B/;

とすれば、$copyにはAをBに変える前のAの時のものが残ります。

が、

($copy = $hoge) =~ s/A/B/;

と書いた場合は、$copyはAがBに変わったもの、$hogeに変わる前のAのときのものが残ります。

正規表現では特殊文字が使えます。

. は改行文字(\x0A \x0D)を除く任意の1字(1バイト)

* は直前のパターンの0回以上の繰り返し

+ は直前のパターンの1回以上の繰り返し

? は直前のパターンが0回または1回現れる

^ は文字列の先頭([]文字クラスの中では「以外」の動作として使います)

$ は文字列の最後

() はパターンのグループ化

[] は文字クラス(A以外としたいとき、[^A]とします)

\ は右隣のメタ文字(特殊文字)を普通の文字として扱う(エスケープ)

↑はほんの一部ですがとりあえずこれだけ。

で、

($ext = $get) =~ s/^.+\.([^\.]+)$/$1/;

を上記の説明に当てはめると

^.+ は、「先頭が1字以上の文字列で始まる」

\. は「文字としての.がひとつ」

[^\.]+ は「文字.以外が1字以上」

([^\.]+) は「↑を囲ってグループ化(つまりこれにマッチしたものが特殊変数$1に入ります。もし、()を複数使っている場合は$1、$2・・・と増えていきます)」

$ は文字列の最後になります。

でこれを

$1で置き換えます。

この場合は([^\.]+)の中身[^\.]+にマッチしたものに置き換わります。

id:zachouR

重ね重ねありがとうございます。

本当に助かりました、また何かありましたら、ぜひよろしくお願いいたします。

頭の下がる重いです、、、m(_ _)m

2006/08/31 14:40:32

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

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

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

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

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