2012-06-24 53 views
3

我有如下的字符串:Perl的正則表達式替換最後一個匹配的字符串

$str = "/dir1/dir2/dir3/file.txt" 

我想從這個字符串中刪除/file.txt

因此,$ str將成爲。

$str = "/dir1/dir2/dir3" 

我正在使用以下正則表達式。但它正在取代一切。

$str =~ s/\/.*\.txt//; 

我怎樣才能讓正則表達式來尋找最後「/」,而不是第一個。

這是什麼正確的正則表達式?

請注意file.txt是不固定的名稱。它可以是任何東西,像FILE1.TXTFILE2.TXT

回答

2

在這個表達式

m/(.*)\/[^\/]*$/ 

第一個子匹配是你正在尋找的路徑。

編輯:

如果您正在尋找替代user1215106的soultion是要走的路:

s/\/[^\/]*$// 
+0

你也忘了逃離角色分類中的分隔符。 – TLP

+0

謝謝改變它 – flec

+0

@Saumita - 您已接受此答案?這對你如何工作?請參閱http://ideone.com/GVagS - 它爲您提供空字符串。它應該是'/(.*)\/[^\/]*$/$ 1 /'或's/\/[^ \ /] * $ //',如我的答案所示。 –

3

很簡單的正則表達式:s/\/[^\/]*$//

+0

它給以下錯誤:最後$應該是\ $或$名稱 – AnonGeek

+0

@Saumitra那是因爲他忘記了他必須越過分隔符'/',即使在角色類中也是如此。 – TLP

+0

抱歉錯字 - 更正了 –

6

如果你想從該字符串的路徑,你可以使用File::Basename。這是因爲Perl版本核心模塊5

perl -MFile::Basename -le '$str = "/dir2/dir3/file.txt"; print dirname($str);' 

在腳本形式:

use strict; 
use warnings; # always use these 
use File::Basename; 

my $str = "/dir1/dir2/dir3/file.txt"; 
print dirname($str);" 

你的正則表達式不起作用,因爲它不固定,而且.*是貪婪的,所以儘可能匹配它可以從它遇到的第一個斜槓/開始。一個工作正則表達式看起來像這些:

$str =~ s#/[^/]*?\.txt$##; 

注意使用非貪婪量詞*?,它將匹配儘可能小的字符串。另外請注意,我使用另一個分隔符來替代,以避免「傾斜牙籤綜合徵」,例如s/\/\/\///

+0

感謝您向我介紹File :: Basename和很好的解釋 – AnonGeek

+0

@Saumitra不客氣。你不應該害怕使用模塊。這個將在你的系統上可用(除非你的perl安裝在20年前)。 – TLP

+3

良好的代碼和良好的建議像往常一樣。但有時我喜歡使用'rindex($ str,'/')'。 – gaussblurinc

相關問題