2015-12-10 87 views
1

我有以下內容的文件input.txt中:猛砸正則表達式匹配*太遠

foo 
[assembly: AssemblyVersion("1.2.3")] 
bar")] 
quux 

以匹配輸入,使用下面的腳本1.2.3

#!/bin/bash 
regex='\[assembly: AssemblyVersion\("(.*)"\)\]' 
fileContent=$(cat input.txt) 
[[ "$fileContent" =~ $regex ]] 
echo "${BASH_REMATCH[1]}" 

我預計輸出爲1.2.3,但它是:

1.2.3")] 
bar 

這是爲什麼?如何解決它?

正則表達式測試程序https://regex101.com按預期工作。

+1

貪婪。嘗試''\ [彙編:AssemblyVersion \(「([^()] *)」\)\]''。 –

+0

@stribizhev哇,很好,確實有效。非常感謝! – alvarez

回答

4

.*被稱爲貪婪點匹配的子模式和它匹配"),任何字符including a newline

因此,限制貪婪最好的訣竅是用否定的字符類[^"]將匹配任何字符,但"(如果有可能的引號字符串中不包括引號):

'\[assembly: AssemblyVersion\("([^"]*)"\)\]' 
           ^^^^^ 

Demo

或 - 如果不應該有()引用的字符串中:

'\[assembly: AssemblyVersion\("([^()]*)"\)\]' 
           ^^^^^ 

Demo

+0

實際上,這裏的兩種解決方案都假設在引用字符串中只有空格,基本標點符號和單詞字符。如果可以有轉義實體,則正則表達式會更復雜一點:[''\ [assembly:AssemblyVersion \(「([^ \\」] *(\\。[^ \\「] *)*)」 \)\]''](http://ideone.com/luGBKQ)。 –

+0

實際上'''* does *匹配換行符;這就是'*'的貪婪導致問題的原因。 – chepner

+0

@chepner:確實,我沒有想到就自動輸入了。 [*在多行表達式中有換行符的情況下,該點將與換行符匹配。*](http://tldp.org/LDP/abs/html/x17129.html#FTN.AEN17189) –