2

この質問は純粋に表面的なものです:

特定の文字列の最後の「/」以降のすべてのテキストを削除したいと思います。したがって、入力が

mkdir -p $DEST/Users/Peter/Dropbox/Public/Vacation/P1000891.jpg

出力は

mkdir -p $DEST/Users/Peter/Dropbox/Public/Vacation/

(正確には、最後の「/」が出力に含まれるかどうかは関係ありません。)

これを行うさまざまな方法を見つけました。たとえば、次のようになります。

my @templist = split "/", 'mkdir -p $DEST/Users/Peter/Dropbox/Public/Vacation/P1000891.jpg';
print join "/", splice(@templist, 0, -1);

または:

my ($a) = 'mkdir -p $DEST/Users/Peter/Dropbox/Public/Vacation/P1000891.jpg' =~ /(.*\/)+(?:[^\/]+)/;
print $a;

しかし、おそらく検索と置換を使用して、正規表現のみを使用してこれを達成できるはずだと思いましたか? 多分先読みで?

4

5 に答える 5

7

文字列の末尾にあるすべての非スラッシュ文字を取り除くだけです:

s|[^/]+$||;

ちなみに、先読みとは、実際にマッチ位置を前に動かさずに、パターンの後のポイントで何かが発生することを確認する方法です。単純なマッチング タスクで必要になることはめったにありませんが、それが何であるかをよく知らない人によって過剰に使用されているようです。

于 2013-03-01T13:29:32.280 に答える
2
use File::Basename qw( dirname );
dirname($path)
于 2013-03-01T13:48:32.583 に答える
1
s/(.*\/).*$/$1/g

以下でテスト:

> echo "a/b/c/d/e/f/remove this"|perl -pe 's/(.*\/).*$/$1/g'
a/b/c/d/e/f/
于 2013-03-01T13:36:36.783 に答える
1

regexperlの両方をタグとして言及しました。問題は (ご存じのとおり) 正規表現が貪欲であることです。この問題を処理するには、次の 2 つの方法があります。

  • 古い方法grep:およびの古いバージョンではsed、正規表現のセットが限られています。あなたがすることは、削除するものにスラッシュを入れたくないという事実を利用することです。

したがって:

$directory =~ s(/[^/]+$)();

(かっこを正規表現の区切り文字として使用しているため、このような丘と谷の影響はありません: s/\/[^\/]//)。これが言っていることは、スラッシュが前にあるすべてのスラッシュ文字を最後から一致させ、その後何も置換しないということです。

ただし、ディレクトリからファイル名を削除したいだけのようです。Perl には、これを処理する方法が組み込まれています。それはdirname関数と呼ばれます:

use File::Basename;

[...];

print "mkdir -p " . dirname $directory . "\n";

これにより、何をしているのかが非常に明確になります。さらに、ディレクトリの区切りに標準のスラッシュを使用しない代替オペレーティング システムでも動作します (Windows!) 。

于 2013-03-01T13:55:23.547 に答える
0

以前のソリューションは私のものよりも優れていますが、それをあなたと共有したいと思います:

perl -e 'my $str = "mkdir -p \$DEST/Users/Peter/Dropbox/Public/Vacation/P1000891.jpg"; my ($res)=$str=~m|(.+/)|; print $res;'

プリント:

mkdir -p $DEST/Users/Peter/Dropbox/Public/Vacation/

だから、m|(.+/)|最後の「/」まで貪欲にむさぼり食います。それから気になる部分に「/」を入れてくださいと言います。

于 2013-03-01T15:46:12.413 に答える