字符类交集算子
&&
,根据其功能的定义,应该是可交换的。
[a&&b]
[b&&a]
对于任何a和b,我发现下面的模式都满足这个标准。
[a-z&&abcd]
等同于
[abcd&&a-z]
[a-z&&ab[cd]]
[ab[cd]&&a-z]
[a-z&&[ab][cd]]
等同于
[[ab][cd]&&a-z]
它们都相当于
[abcd]
[a-z&&[ab]cd]
,这不再是事实。这个表达式只匹配
c
和
d
a
和
b
. 但是,翻转的版本
[[ab]cd&&a-z]
[[ab]cd&a-z]
不同于
[a-z&[ab]光盘]
我调查了
Pattern
为了找出原因,我发现这就是intersection的实现方式(Java 1.8.0u60jdk)
case '&':
// ...
ch = next();
if (ch == '&') {
ch = next();
CharProperty rightNode = null;
while (ch != ']' && ch != '&') {
if (ch == '[') {
if (rightNode == null)
rightNode = clazz(true);
else
rightNode = union(rightNode, clazz(true));
} else { // abc&&def
unread();
rightNode = clazz(false); // here is what happens
}
ch = peek();
}
rightNode = clazz(false);
而不是
rightNode = union(rightNode, clazz(true));
&&
,每当遇到不在嵌套字符类中的第一个字符时,模式解析器假定在它之前没有任何内容。所以之后
&&
,解析器读取
[ab]
rightNode
,然后读取
cd
,但不是与
[阿布]
,它只是覆盖了它。
[a-z&[ab]光盘]
但是,文档仍然暗示它应该可以工作。这是实现中的一个bug,还是应该以这种方式工作?