2017-08-16 25 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