ВНИМАНИЕ: «Никогда» Напишите A-Z
Все экземпляры диапазонов, такие как A-Z
или 0-9
, которые встречаются вне определения RFC, фактически всегда ipso facto неверны в Юникоде. В частности, такие вещи, как [A-Za-z]
, являются ужасными антипаттернами: они являются бесспорными подарками, что программист имеет менталитет пещерного человека в отношении текста, который почти совершенно не подходит для этой стороны тысячелетия. Шаблоны Unicode работают в ASCII, но шаблоны ASCII ломаются в Uniocode, иногда такими способами, которые оставляют вас открытыми для нарушений безопасности. Всегда пишите версию шаблона Unicode независимо от того, используете ли вы данные 1970-х годов или современные Unicode, потому что таким образом вы не облажаетесь, когда фактически используете реальные символьные данные Java. Это похоже на то, как вы используете свой сигнал поворота, даже когда вы «знаете», что за вами никого нет, потому что, если вы ошибаетесь, вы не причиняете вреда, тогда как в противном случае вы наверняка это делаете. Привыкайте использовать 7 категорий Unicode:
\pL
для писем. Обратите внимание, что \pL
намного короче, чем [A-Za-z]
.
\pN
для номеров.
\pM
для знаков, которые объединяются с другими кодовыми точками.
\pS
для символов, знаков и символов. :)
\pP
для пунктуации.
\pZ
для разделителей, подобных пробелам (но не управляющих символов)
\pC
для других невидимых символов форматирования и управляющих символов, включая неназначенные кодовые точки.
Решение
Если вы просто хотите шаблон, вы хотите
^[\pL\pN]+$
хотя в Java 7 вы можете сделать это:
(?U)^\w+$
при условии, что вы не возражаете против подчеркивания и букв с произвольными знаками объединения. В противном случае вы должны написать очень неловко:
(?U)^[[:alpha:]\pN]+$
(?U)
является новым для Java 7. Он соответствует флагу компиляции UNICODE_CHARACTER_CLASSES
класса Pattern. Он переключает классы символов POSIX, такие как [:alpha:]
, и простые ярлыки, такие как \w
, чтобы фактически работать с полным набором символов Java. Обычно они работают только с набором ASCII 1970-х годов, что может быть дырой в безопасности.
Нет способа заставить Java 7 всегда делать это со своими шаблонами без уведомления, но вы можете написать функцию внешнего интерфейса, которая сделает это за вас. Вы просто должны помнить, чтобы звонить своим.
Обратите внимание, что шаблоны в Java до v1.7 нельзя заставить работать так, как UTS # 18 в регулярных выражениях Unicode говорит, что они должны. Из-за этого вы оставляете себя открытым для широкого спектра ошибок, заблуждений и парадоксов, если вы не используете новый флаг Unicode. Например, тривиальный и общий шаблон \b\w+\b
не будет найден где-либо вообще совпадающим внутри строки "élève"
, не говоря уже о его полноте.
Поэтому, если вы используете шаблоны до версии 1.7 Java, вам нужно быть предельно осторожным, гораздо более осторожным, чем кто-либо. Вы не можете использовать ни один из классов POSIX или ярлыков классов, в том числе \w
, \s
и \b
, каждый из которых нарушает все, кроме данных ASCII каменного века. Их нельзя использовать в собственном наборе символов Java.
В Java 7 они могут - но только с правильным флагом.