2013-03-01 121 views
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; 

但我認爲這應該是可以實現的只用一個正則表達式,也許用搜索&替換?也許與前瞻?

回答

6

剛剛獲得在字符串的結尾去掉所有非斜槓:

s|[^/]+$||; 

順便說一句,先行處理的方式來檢查的東西在以後的格局出現,而沒有實際移動比賽位置。這對於簡單的匹配任務來說很少需要,但它似乎被那些不太清楚它是什麼的人所使用。

+2

是的。謝謝。讓我感到內心的溫暖,同時讓我感到很蠢,因爲沒有親眼看到它。 :) – msallge 2013-03-01 13:42:25

1
s/(.*\/).*$/$1/g 

如下測試:

> echo "a/b/c/d/e/f/remove this"|perl -pe 's/(.*\/).*$/$1/g' 
a/b/c/d/e/f/ 
+2

是的,但沒有必要匹配字符串中的所有東西。您只需要匹配您想要刪除的部分。另外,對於要刪除的部分,最好使用'[^ ​​/] *'而不是'。*'。它更具體,因此更容易編寫可靠的正則表達式。 – 2013-03-01 13:40:58

2
use File::Basename qw(dirname); 
dirname($path) 
+0

完全沒有錯,但我明確尋找正則表達式解決方案。 – msallge 2013-03-01 13:50:18

1

你提到的兩個正則表達式perl的的標籤。問題(如你所發現的)是正則表達式是貪婪的。有兩種方式來處理這個問題:

  • 老方法:在老版本的grepsed,你有一組有限的正則表達式。你所做的就是充分利用你不希望刪除的東西的任何斜槓。

這樣:

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

(我用括號爲正則表達式分隔符,所以我沒有小山和峽谷這樣的影響:s/\/[^\/]//)。這是說從現在開始匹配所有正斜槓前面的正斜槓字符,然後不進行任何替換。

但是,它只是看起來像你想從目錄中刪除文件名。 Perl有內置的處理方法。這就是所謂的dirname功能:

use File::Basename; 

[...]; 

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

這使得它非常,非常明確的正是你在做什麼。此外,它完全可以在不使用標準正斜槓目錄分離替代操作系統(咳嗽的Windows!咳嗽

0

以前的解決方案是比我好,但我想與你分享:

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

打印:

的mkdir -p $ DEST /用戶/彼得/ Dropbox的/公共/度假/

因此,m|(.+/)|貪婪地吞噬一切,直到最後一個「/」。然後我們說在我們所關心的部分應該有一個「/」。

相關問題