2010-12-22 40 views
2

對於svn precommit鉤子,我想在將它們提交給服務器之前刪除其中的某些關鍵字的行中的前導空格(當然沒有製表符)。例如,該線路這個perl匹配模式有什麼問題?

MACRO_1 (ABC, "Some String"); 

應匹配和MACRO_1前的前導空格將被刪除。目前,我有以下表達式匹配:

if($line =~ /^\s+MACRO_1|MACRO_2|MACRO_3|MACRO_4.*/) { 
    print "Stripping leading space on line $line\n"; 
    $line =~ s/^\s*//gsxm; # strip leading spaces 
    } 

當我看到控制檯,我得到下面的輸出:

Stripping leading space on line MACRO_1; 
Stripping leading space on line MACRO_2; 
Stripping leading space on line  MACRO_3 (ABC, "Some String"); 
Stripping leading space on line MACRO_1; 
Stripping leading space on line MACRO_2; 
Stripping leading space on line MACRO_1(123); 
Stripping leading space on line MACRO_2(123); 
Stripping leading space on line    MACRO_1; 
Stripping leading space on line MACRO_2; 
Stripping leading space on line MACRO_1; 

這似乎有點混亂給我,因爲有沒有線領導空間,我認爲不會匹配\s+這在我看來一個或多個空間

有什麼問題?

+0

那些修飾符(`/ gsxm`)都不是爲你做(假定`$ line`確實包含一個單行)的替代有用。事實上,它們使速度變慢,因爲`/ m`允許`^`在嵌入換行符後匹配,`/ g`表示它必須尋找另一個匹配。 – cjm 2010-12-22 07:21:28

+0

是複製粘貼的行。感謝提示! – eckes 2010-12-22 07:27:09

回答

10

|最低優先級之間的正則表達式運算符。

所以下面的是一個不正確正則表達式匹配包含字符串或者只foo或僅bar

^foo|bar$ 

因爲它會作爲待處理:

(^foo)|(bar$) 

它匹配任何以foo開頭或以bar結尾的字符串;所以它匹配例如foo11bar

正確的正則表達式將是^(?:foo|bar)$

同樣,在你的情況正確的正則表達式是:

if($line =~ /^\s+(?:MACRO_1|MACRO_2|MACRO_3|MACRO_4).*/) { 

另外請注意,沒有必要後.*的。

您可以縮短你的正則表達式爲:

if($line =~ /^\s+MACRO_[1-4]/) {