みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

ファイル名を正規表現にかける際の文字コードについて

Windows XP, ActivePerl5.8.8 です。
windows 上にあるファイルの名前に沿ってフォルダに振り分けしたく、
以下のようなコードを書きましたが、
ファイル名に日本語の「ソ」などがある場合に
処理がおかしくなります。
文字コードの問題だと思いますが、どうすれば解決できるでしょうか。

++++ここからソース++++++
#!c:/perl/bin/perl.exe
use 5.008;
use strict;
use warnings;
use File::Basename;
use File::Copy;
use File::Path;

my $newdir = "C:/tmp";

for my $filename ( @ARGV ){
main($filename);
print "complete.\n";
}

sub main{

my ($filename) = @_;

my($basename, $basedir) = fileparse($filename);
my($name1, $name2, $ext) = $basename =~ /^(.*) - (.*)(\.[a-zA-Z0-9]+)$/;

mkdir "${newdir}/${name1}";
File::Copy::copy( "${filename}", "${newdir}/${name1}/${basename}" ) or die "${filename} : Cannot copy";
}

1;

投稿日時 - 2009-05-23 15:50:29

QNo.4983557

困ってます

質問者が選んだベストアンサー

正規表現の前に関連する変数値を%エンコードし、正規表現で得た値をデコードすれば一応目的のことはできます。
-----------------------------------------------
#!/usr/bin/perl
use 5.008;
use strict;
use warnings;
use File::Basename;
use File::Copy;
use File::Path;

my $newdir = "tmp";

if(@ARGV){
for my $filename (@ARGV){
$filename=enco($filename);
main($filename);
print "complete.\n";
}
}else{
print <<PR;
USAGE:

[Path/]File
指定フォルダにコピー

F#[Folder] - [Path/]File
フォルダを作成してそこにコピー

[Path/]File - newFile
指定フォルダにnewFile名でコピー


PR
}
sub main{
my ($filename) = @_;
my($basename, $basedir) = fileparse($filename);
my($name1, $name2, $ext) = $basename =~ /^(.*) - (.*)(\.\w+)$/;
$filename=deco($filename);
$basename=deco($basename);
$name1=deco($name1);
$name2=deco($name2);
if($name1=~s/^F#//){
mkdir "$newdir/$name1";
File::Copy::copy("$name2$ext","$newdir/$name1/$name2$ext") or die "$filename : Cannot copy";
}else{
unless($name1){$name1=$filename;$name2=$basename}
$name2.=$name2?"$ext":$name1;
File::Copy::copy("$basedir/$name1","$newdir/$name2") or die "$filename : Cannot copy";
}
}
sub enco{
my($str)=shift;
my(@chars,$unival,$decimal);
foreach(split(/\n/,$str)){@chars=();
(@chars)=(/(?:[\x81-\x9F\xE0-\xFC][\x40-\x7E\x80-\xFC]|[\x20-\xDF])/xg);
foreach(@chars){
if(length($_)==2){s/(.)/sprintf("%%%02X",ord($1))/eg}
$decimal.=$_;
}
}
return $decimal}
sub deco{
my($str)=shift;
$str=~s/%([0-9A-F]{2})/pack("C",hex($1))/ige;
return $str}

投稿日時 - 2009-05-24 21:29:07

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.2

Shift-JIS(CP932)でスクリプトを記述するとだめ文字の問題などがあるので、
Perl5.8以降を使うならスクリプトの文字コードはUTF-8にしたいところです。
しかし、スクリプトの文字コードをUTF-8にしても、
コマンドライン引数や、mkdirの引数などは
Shift-JISで受け渡ししなくてはならないので
いろんな所にencode/decodeを入れる必要が出てきます。

細かいことは以下のページに良くまとまっているので参考にしてください。


WindowsでPerlを使うもんじゃない
http://www.aritia.org/hizumi/perl/perlwin.html

投稿日時 - 2009-05-24 16:34:29

ANo.1

Windows XPなのでファイル名の日本語はShift-JISなのでしょう。
上記正規表現は、Shift-JISでは上手く動作しない場合があります。
EUCに変換するとか、Shift-JIS対応のスクリプトにするなど、
幾つもの方法があります。

投稿日時 - 2009-05-24 09:49:09

あなたにオススメの質問