Как сформировать RegEx строки имени пользователя в Java?
Правила в упражнении:
"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 следует использовать?
Спасибо за Ваше внимание.
Если я хорошо помню из классов 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 (усиление функции, потому что сложно компилировать регулярное выражение).
Причина, по которой регулярное выражение не может делать то, что вы хотите (опять же, если я хорошо помню), заключается в том, что для этой проблемы требуется контекстно-свободная грамматика, а регулярное выражение - регулярная грамматика. Больше
Прежде всего, ||
не является необходимым для этой проблемы, и на самом деле не делает то, что вы думаете. Я только видел, что он используется в группах для регулярных выражений (например, если вы хотите совместить 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 раза. Также не то, что вы хотели.
Легкий способ сделать это - разбить требования на два раздела и создать две строки регулярных выражений, основанные на следующих:
Первое требование довольно просто: нам просто нужно создать класс символов, включая все допустимые символы, и установить ограничения на то, сколько из них может появиться:
"[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...
Я, к сожалению, недостаточно опытен, чтобы понять, как будет выглядеть одно регулярное выражение... Но это, по крайней мере, вполне читаемо.
Попробуйте следующее: [[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]] * $
Надеюсь, я ничего не забыл!
PatternSyntaxExpression
... Не говоря уже о том, что оно также позволяет использовать слишком длинные имена пользователей.
Не может быть элегантным, но вы можете попробовать следующее:
^(([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
Это удовлетворит ваше вышеупомянутое требование. Надеюсь, поможет :)
||
оператор не работает так, как они думают, что они в регулярном выражении