Регулярное выражение (RegEx) для имени пользователя в Java

1

Как сформировать RegEx строки имени пользователя в Java?

Правила в упражнении:

  1. Всего 3 - 10 символов.
  2. Только 'a' - 'z', 'A' - 'Z', '1' - '9', '_' и '.' разрешается.
  3. '_' а также '.' может появиться только 0 - 2 раза.
    • "abc_._"= false
    • "abc..."= false
    • "abc__"= true
    • "abc.."= true
    • "abc_." = true

Если я не буду использовать Regex, это будет проще.


Не рассматривая "1" - "9", я пробовал следующий RegEx, но они не работают.

String username_regex = "[a-zA-Z||[_||.]{0,2}]{3,10}";
String username_regex = "[a-zA-Z]{3,10}||[_||.]{0,2}";

Моя функция:

public static boolean isUserNameCorrect(String user_name) {
    String username_regex = "[a-zA-Z||[_]{0,2}]{3,10}";
    boolean isMatch = user_name.matches(username_regex);
    return isMatch;
}

Какой RegEx следует использовать?

Спасибо за Ваше внимание.

  • 0
    Вы решаете упражнения от Regexone.com
  • 2
    || оператор не работает так, как они думают, что они в регулярном выражении
Показать ещё 2 комментария
Теги:
username

4 ответа

2

Если я хорошо помню из классов CS, не представляется возможным создать одну единственную регулярное выражение, чтобы удовлетворить все три требования. Итак, я бы сделал отдельные проверки для каждого условия. Например, это регулярное выражение проверяет условия 1 и 2, а условие 3 проверяется отдельно.

private static final Pattern usernameRegex = Pattern.compile("[a-zA-Z1-9._]{3,10}");

public static boolean isUserNameCorrect(String userName) {
    boolean isMatch = usernameRegex.matcher(userName).matches();
    return isMatch && countChar(userName, '.')<=2  && countChar(userName, '_') <=2;
}

public static int countChar(String s, char c) {
    int count = 0;
    int index = s.indexOf(c, 0);
    while ( index >= 0 ) {
        count++;
        index = s.indexOf(c, index+1);
    }
    return count;
}

BTW, обратите внимание на шаблон, который позволяет повторно использовать регулярное выражение в Java (усиление функции, потому что сложно компилировать регулярное выражение).

Причина, по которой регулярное выражение не может делать то, что вы хотите (опять же, если я хорошо помню), заключается в том, что для этой проблемы требуется контекстно-свободная грамматика, а регулярное выражение - регулярная грамматика. Больше

1

Прежде всего, || не является необходимым для этой проблемы, и на самом деле не делает то, что вы думаете. Я только видел, что он используется в группах для регулярных выражений (например, если вы хотите совместить Hello или World, вы должны соответствовать (Hello|World) или (?:Hello|World), и в этих случаях вы используете только один |.


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

String username_regex = "[a-zA-Z||[_||.]{0,2}]{3,10}";

Операторы диапазона внутри класса символов не интерпретируются как операторы диапазона, а вместо этого будут представлять литералы, составляющие операторы диапазона. Кроме того, вложенные классы символов просто объединяются. Таким образом, это фактически равно:

String username_regex = "[a-zA-Z_|.{0,2}]{3,10}";

Так что это будет соответствовать определенному сочетанию 3-10 следующим: a - z, A - Z, 0, 2, {, }, . , | , и _.

И это не то, что вы хотели.


String username_regex = "[a-zA-Z]{3,10}||[_||.]{0,2}";

Это будет соответствовать от 3 до 10 a z или A Z, за которыми следуют две трубы, а затем _, | , или . 0 - 2 раза. Также не то, что вы хотели.


Легкий способ сделать это - разбить требования на два раздела и создать две строки регулярных выражений, основанные на следующих:

  1. Только 3 - 10 символов, где только 'a' - 'z', 'A' - 'Z', '1' - '9', '_' и '.' разрешается.
  2. '_' а также '.' может появляться только от 0 до 2 раз.

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

"[a-zA-Z1-9_.]{3,10}"

Тогда я бы подтвердил это "_" и ".". отображаются от 0 до 2 раз:

".*[._].*[._].*"

или

"(?:.*[._].*){0,2}" // Might work, might not. Preferable to above regex if easy configuration is necessary. Might need reluctant quantifiers...

Я, к сожалению, недостаточно опытен, чтобы понять, как будет выглядеть одно регулярное выражение... Но это, по крайней мере, вполне читаемо.

0

Попробуйте следующее: [[aZ] [0-9] [._]? [[AZ] [0-9] [._]? [[AZ] [0-9] *

Niko

EDIT: Вы правы. Затем несколько Regexp: Regex1: ^ [\ w.] {3-10} $ Regex2: ^ [[aZ] [0-9]] [_.]? [[AZ] [0-9]] [_.]? [[Az] [0-9]] * $

Надеюсь, я ничего не забыл!

  • 0
    Это похоже на то, что это PatternSyntaxExpression ... Не говоря уже о том, что оно также позволяет использовать слишком длинные имена пользователей.
0

Не может быть элегантным, но вы можете попробовать следующее:

^(([A-Za-z0-9\._])(?!.*[\._].*[\._].*[\._])){3,10}$

Вот объяснение:

NODE                     EXPLANATION
--------------------------------------------------------------------------------
  ^                        the beginning of the string
--------------------------------------------------------------------------------
  (                        group and capture to \1 (between 3 and 10
                           times (matching the most amount
                           possible)):
--------------------------------------------------------------------------------
    (                        group and capture to \2:
--------------------------------------------------------------------------------
      [A-Za-z0-9\._]           any character of: 'A' to 'Z', 'a' to
                               'z', '0' to '9', '\.', '_'
--------------------------------------------------------------------------------
    )                        end of \2
--------------------------------------------------------------------------------
    (?!                      look ahead to see if there is not:
--------------------------------------------------------------------------------
      .*                       any character except \n (0 or more
                               times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
      [\._]                    any character of: '\.', '_'
--------------------------------------------------------------------------------
      .*                       any character except \n (0 or more
                               times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
      [\._]                    any character of: '\.', '_'
--------------------------------------------------------------------------------
      .*                       any character except \n (0 or more
                               times (matching the most amount
                               possible))
--------------------------------------------------------------------------------
      [\._]                    any character of: '\.', '_'
--------------------------------------------------------------------------------
    )                        end of look-ahead
--------------------------------------------------------------------------------
  ){3,10}                  end of \1 (NOTE: because you are using a
                           quantifier on this capture, only the LAST
                           repetition of the captured pattern will be
                           stored in \1)
--------------------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string

Это удовлетворит ваше вышеупомянутое требование. Надеюсь, поможет :)

  • 0
    Это дает ошибки компиляции ...
  • 0
    Спасибо вам большое! но он показывает мне «Недопустимая escape-последовательность (допустимы \ b \ t \ n \ f \ r \" \ '\\) ". Как ее решить? Замените' \ 'на" \\ "?
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню