2013-10-25 1 views
1

С помощью regex я пытаюсь проверить ввод пользователя, когда он печатает.java regex ввод короче шаблона

My pattern is: "(\\w{3})(\\d{7})(\\w{3})". Допустимый ввод может быть "XYZ0001112CCC".

Я хочу подтвердить его как пользовательский тип. Я имею в виду, что "A", "AB", "ABC", "ABC12", "ABC123", ..., "ABC1234567XY" также не подлежит. Но "A1", "AB2", "ABCD123", ..., "ABC1234567XY1" должен потерпеть неудачу. Пока вход не нарушает правило, я хочу считать его «действительным до сих пор». Возможно ли это с регулярным выражением?

ответ

1

Я хотел бы использовать комбинацию «один раз или вовсе не» квантора для еа ch после первой буквы, и выглядит, чтобы проверить предыдущие части ввода.

Например:

//       |first letters (1 to 3) 
//          | if 3 letters precede... 
//               | digits (1 to 7) 
//                 | if 7 digits precede... 
//                    | 3 letters 
Pattern p = Pattern.compile("[a-zA-Z]{1,3}((?<=[a-zA-Z]{3})\\d{1,7})?((?<=\\d{7})[a-zA-Z]{3})?"); 
String[] inputs = {"XYZ0001112CCC", "A", "AB", "ABC", "ABC12", "ABC123", "A1", "AB2", "ABCD123","ABC1234567XY1"}; 
Matcher m; 
for (String input: inputs) { 
    m = p.matcher(input); 
    System.out.println("Input: " + input + " --> Matches? " + m.matches()); 
} 

Выход:

Input: XYZ0001112CCC --> Matches? true 
Input: A --> Matches? true 
Input: AB --> Matches? true 
Input: ABC --> Matches? true 
Input: ABC12 --> Matches? true 
Input: ABC123 --> Matches? true 
Input: A1 --> Matches? false 
Input: AB2 --> Matches? false 
Input: ABCD123 --> Matches? false 
Input: ABC1234567XY1 --> Matches? false 

Примечание

Я изменил ваше выражение \\w для персонажа класса [a-zA-Z], потому что \\w также проверяет цифры. Альтернативы [a-zA-Z] являются:

  • \\p{Alpha}
  • [a-z] с Pattern.CASE_INSENSITIVE флаг на

Конечная нота

Мой Pattern берет последние буквы как 3-буквенный группу. Если вы также принимаете 1 или 2 буквы, вам нужно только изменить последнее выражение квантора {3} с {1,3}.

+0

Почему ABC12 или ABC123 возвращает false? –

+0

@ Тит мой плохой, я использовал квант «один раз или нет» для всего ввода после 1-го 3-х букв. Исправлена. – Mena

+0

Спасибо @Mena. Сейчас все в порядке. Я не знаком с регулярным выражением. Но вы предлагаете regex для таких ситуаций? Он работает, но это также хорошо в соображениях производительности. Является ли это удобной ситуацией для использования регулярных выражений? –

0

Я рекомендую вам разделить валидацию на два отдельных регулярных выражения: один для действительный так далек валидация и один для окончательной проверки.

Даже тогда это не так, чтобы подтвердить это, например. ABC1 действителен. Образец, подобный (\\w{0,3})(\\d{0,7})(\\w{0,3}), не будет его обрезать, потому что X0C будет считаться действительным. Поэтому я рекомендую вам не пытаться решить эту проблему только с помощью регулярных выражений, но с некоторой кодированной логикой.

(можно сжать всю логику проверки в одно регулярное выражение с использованием либо lookbehinds или if-then-else conditionals, но я предлагаю не делать этого. Это нечитаемое и неосновательное.)

+0

У вас есть предложение «действительно так далеко»? Было бы много возможностей? –

+0

@Tim Вы можете поместить все это в одно регулярное выражение, как показывает Мена в его ответе, хотя вам придется судить сами, принимаете ли вы эту сложность. –

1

Вы можете изменить шаблон, чтобы проще один ([a-zA-Z]+)(\d+)([a-zA-Z]+)

Затем вы можете проверить, сколько писем было в каждой группе:

Pattern p = Pattern.compile("([a-zA-Z]+)(\d+)([a-zA-Z]+)"); 
Matcher matcher = p.matcher("ABC1234567XYZ"); 
if (matcher.find()) { 
    String firstLetters = matcher.group(1); 
    String digits = matcher.group(2); 
    String lastLetters = matcher.group(3); 

    //any checks here 
} 
+0

IllegalStateException: Совпадений не найдено. –

+0

Странно, что он не нашел ни одного матча. Я также обновил шаблон, так как \ w принимает также подчеркивание + числа и + требуется, по крайней мере, для одного совпадения. – Admit

+0

Я думаю, что ваш предложенный шаблон должен быть: ([a-zA-Z] *) (\\ d *) ([a-zA-Z] *). Это тоже хорошее решение, но решение Mena кажется мне лучше, поскольку все проверки выполняются в регулярном выражении. –

0

Поскольку формат довольно легко, вы могли бы сделать что-то вроде этого (я не знаю точного синтаксиса Java, но я думаю, что идея ясна):

String input = "DEF3"; 
String example = "ABC1234567XY"; 
Pattern regex = Pattern.compile("(\\w{3})(\\d{7})(\\w{3})"); 

String test_input = input + example.last_digits(example.length-input.length); 
Matcher matcher = p.matcher(test_input); 
return matcher.find(); 

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

 Смежные вопросы

  • Нет связанных вопросов^_^