Проверка определенных строк с помощью регулярного выражения - PullRequest
0 голосов
/ 24 августа 2011

У меня есть список произвольной длины типа String, я должен убедиться, что каждый элемент String в списке является буквенно-цифровым или числовым без пробелов и специальных символов, таких как - \ / _ и т. Д.

Пример допустимых строк:

J0hn-132ss/sda
Hdka349040r38yd
Hd(ersd)3r4y743-2\d3
123456789

Примеры недопустимых строк:

Hello
Joe
King

и т. Д. В основном нет слов.

В настоящее время я использую stringInstance.matches("regex"), но не слишком уверен в том, как написать соответствующее выражение

if (str.matches("^[a-zA-Z0-9_/-\\|]*$")) return true; 
else return false;

Этот метод всегда возвращает true для слов, которые не соответствуют формату, который я упомянул.

Описание регулярного выражения, которое я ищу на английском, будет выглядеть примерно так:
Любая строка, где строка содержит символы из (a-zA-Z И 0-9 И специальные символы)
ИЛИ (0-9 И специальные символы)
ИЛИ (0-9)

Редактировать : Я пришел к следующему выражению, которое работает, но я чувствую, что оно может быть плохим с точки зрения его непонятности или сложности.

Выражение:

(([\\pL\\pN\\pP]+[\\pN]+|[\\pN]+[\\pL\\pN\\pP]+)|([\\pN]+[\\pP]*)|([\\pN]+))+

Я использовал этот сайт, чтобы помочь мне: http://xenon.stanford.edu/~xusch/regexp/analyzer.html
Обратите внимание, что я все еще плохо знаком с регулярным выражением

Ответы [ 4 ]

11 голосов
/ 24 августа 2011

ВНИМАНИЕ: «Никогда» Напишите A-Z

Все экземпляры диапазонов, такие как A-Z или 0-9, которые встречаются вне определения RFC, фактически всегда ipso facto неверны в Юникоде. В частности, такие вещи, как [A-Za-z], являются ужасными антипаттернами: они являются бесспорными подарками, что программист имеет менталитет пещерного человека в отношении текста, который почти совершенно не подходит для этой стороны тысячелетия. Шаблоны Unicode работают в ASCII, но шаблоны ASCII ломаются в Uniocode, иногда такими способами, которые оставляют вас открытыми для нарушений безопасности. Всегда пишите версию шаблона Unicode независимо от того, используете ли вы данные 1970-х годов или современные Unicode, потому что таким образом вы не облажаетесь, когда фактически используете реальные символьные данные Java. Это похоже на то, как вы используете свой сигнал поворота, даже когда вы «знаете», что за вами никого нет, потому что, если вы ошибаетесь, вы не причиняете вреда, тогда как в противном случае вы наверняка это делаете. Привыкайте использовать 7 категорий Unicode:

  1. \pL для писем. Обратите внимание, что \pL намного короче, чем [A-Za-z].
  2. \pN для номеров.
  3. \pM для знаков, которые объединяются с другими кодовыми точками.
  4. \pS для символов, знаков и символов. :)
  5. \pP для пунктуации.
  6. \pZ для разделителей, подобных пробелам (но не управляющих символов)
  7. \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 они могут - но только с правильным флагом.

1 голос
/ 25 августа 2011

Можно изменить описание необходимого регулярного выражения на «содержит хотя бы одно число», чтобы следующий код работал /.*[\pN].*/. Или, если вы хотите ограничить поиск буквенными цифрами и пунктуацией, используйте /[\pL\pN\pP]*[\pN][\pL\pN\pP]*/. Я протестировал его на ваших примерах, и он отлично работает.

Вы можете дополнительно уточнить свое регулярное выражение, используя ленивые квантификаторы, подобные этому /.*?[\pN].*?/. Таким образом, быстрее не получится, если нет чисел.

Я хотел бы порекомендовать вам отличную книгу по регулярным выражениям: Освоение регулярных выражений , в ней есть отличное введение, подробное объяснение того, как работают регулярные выражения, и глава о регулярных выражениях в java.

0 голосов
/ 24 августа 2011

Здесь приведен частичный ответ, который содержит 0-9 и специальные символы ИЛИ 0-9.

^([\d]+|[\\/\-_]*)*$

Это можно прочитать как ((1 или более цифр) ИЛИ(0 или более специальных символов \ / - '_')) 0 или более раз.Он требует цифры, принимает только цифры и отклоняет строки, состоящие только из специальных символов.

Я использовал regex tester для проверки нескольких строк.

Добавлениебуквенные символы кажутся простыми, но может потребоваться повторение данного регулярного выражения.

0 голосов
/ 24 августа 2011

Похоже, вы просто хотите убедиться, что в строке нет пробелов. Если это так, вы можете сделать это очень просто:

return str.indexOf(" ") == -1;

Это вернет true, если пробелов нет (допустимо, насколько я понимаю ваши правила), и false, если в строке есть пробел (неверно).

...