Обновление: в Java 11 ошибка, описанная ниже, кажется, исправлена
(возможно, это было исправлено еще раньше, но я не знаю, в какой именно версии. Отчет об ошибке, связанной с аналогичной проблемой, связанной с ответом nhahtdh, предлагает Java 9).
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]
внутри них?