2017-08-16 27 views
1

bash運算符=~如bash手冊尊重區域的Conditional Constructs部分中所述?bash運算符=〜尊重區域設置嗎?

文檔暗示它使用POSIX擴展正則表達式到:

字符串給操作者的右側被認爲是一個擴展正則表達式,並相應地匹配(如在regex3)

的POSIX擴展正則表達式手冊頁man 7 regex描述它們是區域設置相關的。特別是關於方括號表達式,它說:

如果列表中的兩個字符之間用' - '分隔,這是整理序列中這兩個(包含)之間的字符的全部範圍的簡寫,例如「 「ASCII」中的「[0-9]」與任何十進制數字匹配。 ...範圍非常依賴於排序順序,可移植程序應該避免依賴它們。

所有這一切都暗示了與bash =~運算符一起使用的正則表達式應該尊重語言環境;但是我的測試似乎並沒有證實這一點:

$ export LANG=en_US 
$ export LC_COLLATE=en_US 
$ [[ B =~ [A-M] ]] && echo matched || echo unmatched 
matched 
$ [[ b =~ [A-M] ]] && echo matched || echo unmatched 
unmatched 

我希望最後的命令也呼應matched作爲對照序列en_USaAbBcCdD...,而不是在C(ASCII)語言環境的ABCD...abcd...序列。

錯誤地設置我的語言環境嗎? bash是否不正確地爲POSIX擴展正則表達式設置區域以使用區域設置?


根據馬科斯的回答一些更多的實驗:

en_US區域,[a-M]顯然是經過z任何小寫字符a任何大寫字符A通過M匹配。這將暗示整理順序爲abcd...ABCD...而不是aAbBcCdD...。使用[a-M]切換到C區域設置將導致來自條件構造的2的退出代碼而不是01。這表示無效的正則表達式,這在C區域設置a之後出現在整理順序中的M之後是有意義的。

因此,locale肯定是在POSIX擴展正則表達式中使用的。然而,括號表達式並不遵循我所期望的整理順序。括號表達式可能使用除排序順序之外的其他東西嗎?


EDIT1:更新爲使用實際正確en_US整理順序。
edit2:增加了進一步的發現。

+2

不是你的問題的解決,但'回聲$ '一\ NB \ NC \鈉\ NB \ NC' | sort'表示'a'在美國語言環境中的*'A'之前排序*。更好的例子是'g'(或者'b..l'中的任何東西)。 –

+0

按照預期在cygwin中工作:'export LC_COLLATE = en_US && [[b =〜[A-M]]] && echo match' yield match。 – yacc

+0

@yacc,hmmn,有趣。我只是使用glibc提供的語言環境。看看類似'ls'的輸出結果似乎表明整理順序是正確的,所以爲什麼bash表現得如此奇怪...... – wich

回答

2

它實際上是aAbB ...而不是AaBb。
試試這個:touch {a..z}; touch {A..Z}; ls -1 | sort
請參閱?

所以

$ [[ a =~ [a-M] ]] && echo matched || echo unmatched 
matched 
$ [[ A =~ [a-M] ]] && echo matched || echo unmatched 
matched 
+0

這不回答主要的OP問題。即使正確的順序是OP所寫的'aBB ...'而不是'AaBb ...',我們也希望在這個測試中有一個「匹配」:'[[b =〜[AM]]] && echo matched | |回聲不匹配'。但我們仍然獲得「無與倫比」的結果。使用'[a-M]'的解決方案只能工作,因爲它實際上包含了'a到z',然後是'A到M',就像出現在C語言環境中一樣。 –

+1

呵呵,的確,它是'aAbBcC ...''從來不知道那個。我會更新問題的正確性。但事實上,正如喬治所說,即使在測試中使用'b'而不是'a',測試仍然失敗。 – wich

+0

但是我的答案在這裏適用,GNU bash,4.3.46(7)版本(i686-pc-cygwin)。 'export LC_COLLATE = en_US && [[b =〜[A-M]]] && echo match':match。 – yacc