Ошибка в двойном отрицании классов символов регулярных выражений?
TL; DR
Зачем[^\\D2]
, [^[^0-9]2]
, [^2[^0-9]]
получить разные результаты в Java?
Код, используемый для тестов. Вы можете пропустить это сейчас.
String[] regexes = { "[[^0-9]2]", "[\\D2]", "[013-9]", "[^\\D2]", "[^[^0-9]2]", "[^2[^0-9]]" };
String[] tests = { "x", "1", "2", "3", "^", "[", "]" };
System.out.printf("match | %9s , %6s | %6s , %6s , %6s , %10s%n", (Object[]) regexes);
System.out.println("-----------------------------------------------------------------------");
for (String test : tests)
System.out.printf("%5s | %9b , %6b | %7b , %6b , %10b , %10b %n", test,
test.matches(regexes[0]), test.matches(regexes[1]),
test.matches(regexes[2]), test.matches(regexes[3]),
test.matches(regexes[4]), test.matches(regexes[5]));
Допустим, мне нужно регулярное выражение, которое будет принимать символы, которые
не цифры,за исключением2
.Таким образом, такое регулярное выражение должно представлять каждый символ, кроме0
, 1
, 3
,4
...,9
, Я могу написать это по крайней мере двумя способами, которые будут суммойвсе, что не является цифрой с2:
[[^0-9]2]
[\\D2]
Оба эти регулярных выражения работают как ожидалось
match , [[^0-9]2] , [\D2]
--------------------------
x , true , true
1 , false , false
2 , true , true
3 , false , false
^ , true , true
[ , true , true
] , true , true
Теперь допустим, что я хочу изменить принятые символы. (поэтому я хочу принять все цифры, кроме 2) Я мог бы создать регулярное выражение, которое явно содержит все принятые символы, такие как
[013-9]
или попытайтесь опровергнуть два ранее описанных регулярных выражения, поместив их в другое[^...]
лайк
[^\\D2]
[^[^0-9]2]
или даже
[^2[^0-9]]
но к моему удивлению только первые две версии работают как положено
match | [[^0-9]2] , [\D2] | [013-9] , [^\D2] , [^[^0-9]2] , [^2[^0-9]]
------+--------------------+-------------------------------------------
x | true , true | false , false , true , true
1 | false , false | true , true , false , true
2 | true , true | false , false , false , false
3 | false , false | true , true , false , true
^ | true , true | false , false , true , true
[ | true , true | false , false , true , true
] | true , true | false , false , true , true
Итак, мой вопрос почему[^[^0-9]2]
или же[^2[^0-9]]
не ведет себя как[^\D2]
? Могу ли я как-то исправить эти регулярные выражения, чтобы я мог использовать[^0-9]
внутри них?