1

私は持っています

$w="/fold1/fold2/qwerty.h"

/qwerty.hをカットして/fold1/fold2を取得したい

私は試した

$w=~s/\/.+\.h\z//; and $w=~s/\/.+?\.h\z//;

しかし、それらは文字列全体を削除します。

$w=~s/\/\w+\.h\z//;

動作しますが、qwerty.hの代わりにqwe\rty.hがあるとします。それは二度と機能しません。

4

4 に答える 4

7

標準ライブラリのモジュールの1つであるFile::Basenameを使用します。

 use File::Basename;
 my $dir = dirname( $path );

一般に、データが特定のタイプであることがわかっている場合は、それらをそのタイプとして扱うようにしてください。この場合、それがファイルパスであることがわかっているので、一般的な文字列のように扱うのではなく、ファイルパスのように扱います。

于 2012-04-06T20:56:33.873 に答える
1

あなたがしていることについて考えてください。最後の後に削除したいので、パターンは「任意の文字」()や「単語文字」()ではなく、/に基づいている必要があります/.\w

$w =~ s/\/[^\/]+\.h\z//;

/これは、正規表現区切り文字として回避することで、より明確に記述されます。

$w =~ s,/[^/]+\.h\z,,;

とは言うFile::Basenameものの、よりクリーンでより一般的にポータブルなソリューションです。

于 2012-04-06T19:31:20.497 に答える
0

File::Basenameうまくいかない場合は、次のようにすることができます。

substr( $w, 0, rindex( $w, '/' ))

私はこれを頻繁に使用するので、これについていくつかのイディオムがあります。

sub rpos_of {
    return unless 1 + ( my $pos = rindex( $_[0], $_[1] )); 
    return $pos || '0E0';
}
sub before_last { 
    return $_[0] unless my $pos = &rpos_of;
    return substr( $_[0], 0, $pos );
}
sub after_last  { 
    return $_[0] unless my $pos = &rpos_of;
    return substr( $_[0], $pos + length( $_[1] )); 
}
sub break_at_last { 
    return $_[0] unless my $pos = &rpos_of;
    return ( substr( $_[0], 0, $pos )
           , substr( $_[0], $pos + length( $_[1] ))
           );
}
于 2012-04-06T21:15:16.950 に答える
0
$w=~s#(.*)/[^/]+#\1#

これも機能します。最後の/を見つけて、文字列全体を最後の/の前の部分文字列に置き換えます。

于 2012-04-10T01:24:15.397 に答える