私はこのディレクトリパスを持っています:
\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1
testQEM.txt
上記の文字列からファイル名を取得するにはどうすればよいですか?
私はこれを使用します:
$file =~ /(.+\\)(.+\..+)(\\.+)/;
しかし、次の結果が得られます。
file = testQEM.txt\main\ABC_QEM
ありがとう、
ジロン
パスの途中にファイルノードを含めることはできないため、理解できません。複数のパスが何らかの形で連結されていますか?
とにかく、次を使用して実際のファイルとして検証される最初のノードを探すパスをたどることをお勧めします-f
ここに例があります
use strict;
use warnings;
my $path = '\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1';
my @path = split /\\/, $path;
my $file = shift @path;
$file .= '\\'.shift @path until -f $file or @path == 0;
print "$file\n";
ディレクトリ名にはピリオドが含まれている可能性があるため、これは少し難しいです。これは特に *nix システムに当てはまりますが、Windows でも有効です。
したがって、可能性のある各サブパスは、ファイル性について繰り返しテストする必要があります。
私は多分このようなことを試してみます:
my $file;
my $weirdPath = q(/main/ABC_PRD/ABC_QEM/1/testQEM.txt/main/ABC_QEM/1);
my @parts = split m{/} $weirdPath;
for my $i (0 .. $#parts) {
my $path = join "/", @parts[0 .. $i];
if (-f $path) { # optionally "not -d $path"
$file = $parts[$i];
last;
}
}
print "file=$file\n"; # "file=testQEM.txt\n"
私split
はすべてのスラッシュで奇妙なパスです (相互運用性が問題にならない場合は、バックスラッシュに変更してください)。次に、最初の$i+1
要素を結合して、パスが通常のファイルかどうかをテストします。その場合は、パスの最後の部分を保存してループを終了します。
ファイルがピリオドを含むパスの唯一の部分であることを保証できる場合は、他のソリューションのいずれかを使用することをお勧めします。
/[^\\]+\.[^\\]+/
.
2 つのバックスラッシュで区切られたものをキャプチャします。これはあなたが探しているものですか?
my $file = '\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1';
my ($result) = $file =~ /\\([^\\]+\.[^\\]+)\\/;
$result を囲む括弧は、右側の式のリスト コンテキストを強制し、括弧内に一致するものを返します。
>echo "\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1"|perl -pi -e "s/.*([\\][a-zA-Z]*\.txt).*/\1/"
\testQEM.txt
* と + がどのように機能するかなど、正規表現のバックトラッキングの原則を理解することをお勧めします。次のように正規表現を少し変更するだけです。
/(.+\\)(.+\..+?)(\\.+)/
正規表現パターンを使用/(?=[^\\]+\.)([^\\]+)/
my $path = '\main\ABC_PRD\ABC_QEM\1\testQEM.txt\main\ABC_QEM\1';
print $1 if $path =~ /(?=[^\\]+\.)([^\\]+)/;
このコードをここでテストします。