2014-06-11 33 views
2

我想使用Bash正則表達式匹配(使用=〜運算符)來匹配包含引號的字符串。我想提取引號之間的文本:使用Bash正則表達式匹配(=〜)其中正則表達式包含引號(「字符)

foo='"Hello World!"' 

我的第一次嘗試是把正則表達式強引號,像這樣給力的報價是常規字符

[[ "$foo" =~ '".*"' ]] 

失敗,因爲Bash解釋這是一個字符串匹配而不是正則表達式。

然後我試圖使用\引號,像這樣:

[[ "$foo" =~ \".*\" ]] 

失敗(編輯:其實,事實並非如此。它會失敗,如果在\「和]之間沒有空格,但這裏的版本工作得很好),因爲第一個\是在純bash文本中,並且無法轉義引號(我認爲,VIM中的着色表示第二個引號是逃脫但不是第一個,運行腳本失敗)

那麼有什麼辦法可以逃避「字符而不將正則表達式匹配轉換爲字符串匹配?

+3

'foo ='「Hello World!」'; [[「$ foo」=〜\「。* \」]] && echo「match」適用於我,Vim語法突出顯示(順便說一句,不會以任何方式影響代碼)很好。 –

+3

用一粒鹽來突出語法,特別是在正則表達式周圍。大多數語法高亮引擎不是強大的詞法分析器或解析器,並且(最相關的)不是與要讀取代碼的實際解釋器所使用的* same *詞法分析器或解析器。 – kojiro

+0

啊,這個問題顯然是我在真正的程序中使用它之後沒有在\「和\]之間使用空格,Bash以混亂的方式處理空格 – DroidFreak

回答

9

其實,你的第二次嘗試對我的作品在bash 3和4:

$ echo "$BASH_VERSION" 
3.2.51(1)-release 
$ echo "$foo" 
"Hello World!" 
$ [[ "$foo" =~ \".*\" ]] && echo $BASH_REMATCH 
"Hello World!" 

$ echo "$BASH_VERSION" 
4.3.18(1)-release 
$ echo "$foo" 
"Hello World!" 
$ [[ "$foo" =~ \".*\" ]] && echo "${BASH_REMATCH[0]}" 
"Hello World!" 

但是要談理論了一秒鐘,這一切都與慶典如何解釋表達作爲一個整體來做。

$ [[ $foo =~ '"'.*'"' ]] && echo $BASH_REMATCH 
"Hello World!" 

但也許所有的最簡單方法是使用第二個變量來保存:只要正則表達式字符本身中沒有報價,表達式的其餘部分可以在沒有副作用的被引用正則表達式本身。

$ exp='".*"' 
$ [[ $foo =~ $exp ]] && echo $BASH_REMATCH 
"Hello World!" 
+0

正如我在對OP的評論中所說的事實證明這個問題是在我的實際程序中缺少「和」]之間的空格。我可能應該在我說它不起作用之前進行測試。儘管如此,我絕對更喜歡第三塊代碼中的方法。這樣VIM的文字着色不會被搞砸,我不必輸入太多的強引號來逃避RE中的引號。 – DroidFreak

+0

另外請注意,在Bash 3.1-3.2中,他們改變了引號的工作方式,默認爲準確的字符串匹配,所以最好的辦法是使用示例3來處理更新和更舊的版本。 – dragon788