2014-02-22 82 views
0

這些片段似乎等同於我:爲什麼替代正則表達式失敗?

$ perl -E ' 
my $var="/usr/local/bin/gcc"; 
$var =~ s/([^\/]*)$/$1/; 
print "$var\n";' 
/usr/local/bin/gcc 

$ perl -E ' 
my $var="/usr/local/bin/gcc"; 
$var =~ /([^\/]*)$/; 
print "$1\n";' 
gcc 

然而,在片段1替代不起作用。它打印/usr/local/bin/gcc而不是gcc$1是正確的,如第二個片段所證明的。
這裏有什麼問題?

回答

1

您的替換是在字符串末尾找到與[^\/]*匹配的文本,並將其替換爲匹配的文本(即它是一個標識操作)。

第二個例子是隻輸出匹配的文本,在忽略不匹配的字符串的開頭文字..

如果你希望你的第一個例子,以執行相同的操作作爲第二個你應該嘗試修改您的模式:s/^.*?([^\/]*)$/$1/

+0

這將打印什麼:'$ perl的-E' 我是$ var = 「在/ usr/local/bin目錄/ gcc的」; $ var =〜s /^.*([^\/]*)$/$ 1 /; print「$ var \ n」;'' – Jim

+0

對。我忘了添加一個?阻止第一個*被貪婪。 –

2

您的期望等效有點不對。一個相當於第二個例子是說:

$ perl -E ' 
my $var="/usr/local/bin/gcc"; 
$var =~ s/.*?([^\/]*)$/$1/; 
print "$var\n";' 
gcc 

你正在做什麼是簡單地捕獲一組的模式和用自身替換這樣捕獲組。那將是顯而易見的了,你試着用什麼代替了比賽:

$ perl -E ' 
my $var="/usr/local/bin/gcc"; 
$var =~ s/([^\/]*)$//; 
print "$var\n";' 
/usr/local/bin/ 
0

沒有爲您的特殊應用更加便攜的解決方案。使用核心模塊來操縱文件路徑總是一個好主意。因此,我建議以下

$ perl -MFile::Basename -E ' 
my $var="/usr/local/bin/gcc"; 
print scalar fileparse($var), "\n";' 
gcc 
相關問題