dポイントプレゼントキャンペーン実施中!

いつもお世話になります。
ファイルアップロードし、アップロードしたファイル名を記録するプログラムを
作成しております。(ファイル名を記録し、別プログラムでファイル名にリンクを張ります。)
この中でアップロードファイル名がc:\temp\cgi\test.cgiやc:\mydocument\test\temp\cgi\test.cgiと
いったものも含め実ファイル名(test.cgi)のみを抜きだして記録したいのですが、上手くいきません。
ファイル名を切り出す方法を教えていただきましたが、こちらも上手くいきませんでした。
$inLink =~ s/^.*[\\\/]//;と記述。

どなたかご教示お願いいたします。

A 回答 (8件)

#7>$inLINK =~ s/^.*\\//;を解説していただければ助かります。


#1の方が書いていらっしゃるように、ファイル名以外の部分を取り除きます。
変数 =~ s/パターン/置き換える文字列/;
は、変数でパターンにマッチングした部分を"置き換える文字列"で置き換えます。
^ は、先頭を表すパターンで
.* は、一文字の0回以上の繰り返しパターン
\\ は、円マーク\ ですが、\ 自体が次のパターン文字をパターンとして認識させないという機能を持つ記号なので、\\のように2つ続けて書く必要があります。
つまり、先頭から、\までを"何もない"と置き換える、即ち取り除くという意味になります。
この場合、.* は、より長くマッチしようとするので、フォルダの階層が深くて \ マークが複数在った場合でも最後の \ マークまで取り除くことができます。
    • good
    • 0
この回答へのお礼

BLUEPIXY様おはようございます。無理なお願いに対応していただきありがとうございました。おかげさまで理解が進みました。BLUEPIXY様含め今回の件は皆さんに感謝いたします。本当にありがとうございました。

お礼日時:2006/05/01 08:58

#5補>


>$inLink =~ /(^.*\\)(.*)/;
>open(OUT, "> ../upload/$inLINK");
は、ダメです。
>$inLink =~ /(^.*\\)(.*)/;
の部分では、s/…/…/をしていませんから、マッチングをさせているだけですから$inLink は置き換えられていません。
マッチングが成功した場合には
open(OUT, "> ../upload/$2");
のようにすればいいと思います。
また、$inLink を置き換えた場合には
>open(OUT, "> ../upload/$inLINK");
の$inLINK は、"LINK" が大文字になっているため別の変数になっています。同じ変数名を使う必要があります。

この回答への補足

BLUEPIXY様:回答が遅れて申し訳ありません。変数名の件お恥ずかしながらミスでした。ご指摘ありがとうございます。冷静な目が必要ですね
。結局下記のようにして動作いたしました。沢山の方々にサポートしていただき助かりました。不勉強で申し訳ありませんが、~ /(^.*\\)*)/;を解説していただければ助かります。
if ($inLINK ne '')
{
while ($bytesread = read($inLINK, $buffer, $BUFSZ))
{
$file .= $buffer;
}
$inLINK =~ s/^.*\\//;
open(OUT, "> ../upload/$inLINK");
binmode(OUT);
print(OUT $file);
close(OUT);
}

補足日時:2006/04/30 23:43
    • good
    • 0

use strict;


を使われることをおすすめします。
Perlでは大文字と小文字を区別しますから。
basenameが使えないのもこれで解消できればいいのですが、、、


私が知ってる各OSのデリミタは
UNIX(UNIX like OS) /
Windows(DOS) \ (ドライブとパスの区切りに:を使用)
Mac Classic :
MacOS X /
です。

私はデリミタで分割して最後の部分を取り出してましたけどね(^^;
Perlの場合は、

if(($pos=rindex($inLink,'/'))>=0){
$inLink = substr($inLink, $pos+1);
}elsif(($pos=rindex($inLink,'\\'))>=0){
$inLink = substr($inLink, $pos+1);
}elsif(($pos=rindex($inLink,':'))>=0){
$inLink = substr($inLink, $pos+1);
}
print $inLink;

こんな感じで出来たと思いますが、正規表現で不要部分を消しちゃった方がスマートかも(^^;

ファイル名の取得方法はどのようにされてますか?
<form action="" method="post" enctype="multipart/form-data">
で送信されている場合は、
filename=~
という行が書き出されますが、このときのファイル名は、
ブラウザがデリミタを変更する場合もあるので、クライアントのOSに関係なく、すべてをチェックした方が良いと思います。

この回答への補足

taloo様ご回答ありがとうございます。
とりあえずuse strict;を使用してみます。
それから下記部分のご解説をお願いします。
form action="" ~はご指摘の通り記述しております。
「filename=~で書き出される」、「クライアントのOSに関係なく~」の箇所が不勉強で理解できませんでした。
--------------------------------------------------
<form action="" method="post" enctype="multipart/form-data">
で送信されている場合は、
filename=~
という行が書き出されますが、このときのファイル名は、
ブラウザがデリミタを変更する場合もあるので、クライアントのOSに関係なく、すべてをチェックした方が良いと思います。

補足日時:2006/04/28 11:27
    • good
    • 0

#3>basenameが上手く動作していないみたい


う~ん、なんでですかね~。
#3がうまくいかないのは、OS間でファイルパスの記述が異なるからかもしれませんけど、
#1,2,4でうまくいかない理由がわからないですね。
本当に、切り出そうとしている $inLink にc:\mydocument\test\temp\cgi\test.cgi のような文字列が入っているんでしょうか?

この回答への補足

BLUEPIXY様おはようございます。何度もテストしました。例えばC:\TEMP\CGI\test\upload4\readme.txtファイルを切り出そうと思い下記記述をしてみましたが、上手くいっておりません。ファイルは「C:\TEMP\CGI\test\upload4\readme.txt」でアップロードされファイル名は記録されていません。
$BUFSZ = 2048;
$file = '';
$buffer = '';
if ($inLINK ne '')
{
while ($bytesread = read($inLINK, $buffer, $BUFSZ))
{
$file .= $buffer;
}
$inLink =~ /(^.*\\)(.*)/;
open(OUT, "> ../upload/$inLINK");
binmode(OUT);
print(OUT $file);
close(OUT);
}
---------------------------------------
ファイル記述は下記の通りです。
seek(DATA, 0, 0);
print DATA $tNum."\n";
print DATA @tData;
print DATA $tNum."<>".$inTITLE."<>".$inMAIN."<>".$inDATE."<>".$inSEL."<>".$inLink."<>".$inFLAG."<>".$inCATE."\n";
truncate(DATA, tell(DATA));
close(DATA);
&unlock;
私では手に負えません。ヒントなどなんでも結構ですので教えて下さい。

補足日時:2006/04/28 09:36
    • good
    • 0

use strict;


my $up_file = 'c:\mydocument\test\temp\cgi\test.cgi'; # としたとき、
my $up_file_name = ( split /[\/\\]/, $up_file )[-1];
print "$up_file_name\n";
    • good
    • 0

use File::Spec;


$file=q(c:\temp\test.txt);
($volume, $directories, $filename)=File::Spec->splitpath($file);
print "$filename\n";

use File::Basename;
$filename = basename($file);
print "$filename\n";

この回答への補足

BLUEPIXY様ご回答ありがとうございます。テストしてみましたが、ファイル名が入りませんでした。どうやらbasenameが上手く動作していないみたいです。環境の設定などございますでしょうか?
プログラムの先頭付近にuse File::Basename;を記述し、
ファイル名を書き込み所で$filename = basename($file);を記述しております。

補足日時:2006/04/27 19:57
    • good
    • 0

#1です。


もうひとつこんなのを。

$inLink =~ /(^.*\\)(.*)/;
print "$2\n";

こっちのほうが抜き出してる感じですかね。
    • good
    • 0

こんなんですかねぇ。



$inLink =~ s/^.*\\//;

でもこれだと切り出すというよりは余計な部分を削除してるだけですが。

この回答への補足

ttyp03様ご回答ありがとうございます。テストしていた為回答が遅くなりました。色々やってみたのですが、ファイル名が変わりませんでした。c:\mydocument\test\temp\cgi\test.cgi等をアップロードするとそのまま(c:\mydocument\test\temp\cgi\test.cgiという風に)記録されてしまいます。クライアントは(windows多数、MACも多少あり。)サーバーはlinuxです。引き続きサポート願えれば幸いです。

補足日時:2006/04/27 18:05
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!