Использование Matcher.hitEnd()
. Этот метод предназначен именно для определения того, может ли дополнительный вклад изменить результат. Таким образом, если шаблон не совпадает и конец не достигнут, добавление большего количества символов в конец не решит проблему. Это не исключает того, что вставка в другую позицию может решить эту проблему:
static final Pattern VALID_MAIL = Pattern.compile(…);// insert actual pattern here
enum Status { VALID, INVALID, INCOMPLETE }
static Status check(CharSequence cs, boolean complete) {
Matcher matcher = VALID_MAIL.matcher(cs);
if(matcher.matches()) return Status.VALID;
return complete || !matcher.hitEnd() ? Status.INVALID : Status.INCOMPLETE;
}
Для имитации набора текста:
String[] samples = { "eshaka@horm", "some_one@some@ma",
"some_one@somemail.com", "@domain.name" };
for(String input: samples) {
StringBuilder typing = new StringBuilder();
input.codePoints().forEach(cp -> {
System.out.println(typing.appendCodePoint(cp) + ": "
+ check(typing, typing.length()==input.length()));
});
System.out.println();
}
При использовании шаблона, используемого в вашем вопросе, это приводит к:
e: INCOMPLETE
es: INCOMPLETE
esh: INCOMPLETE
esha: INCOMPLETE
eshak: INCOMPLETE
eshaka: INCOMPLETE
eshaka@: INCOMPLETE
eshaka@h: INCOMPLETE
eshaka@ho: INCOMPLETE
eshaka@hor: INCOMPLETE
eshaka@horm: INVALID
s: INCOMPLETE
so: INCOMPLETE
som: INCOMPLETE
some: INCOMPLETE
some_: INCOMPLETE
some_o: INCOMPLETE
some_on: INCOMPLETE
some_one: INCOMPLETE
some_one@: INCOMPLETE
some_one@s: INCOMPLETE
some_one@so: INCOMPLETE
some_one@som: INCOMPLETE
some_one@some: INCOMPLETE
some_one@some@: INVALID
some_one@some@m: INVALID
some_one@some@ma: INVALID
s: INCOMPLETE
so: INCOMPLETE
som: INCOMPLETE
some: INCOMPLETE
some_: INCOMPLETE
some_o: INCOMPLETE
some_on: INCOMPLETE
some_one: INCOMPLETE
some_one@: INCOMPLETE
some_one@s: INCOMPLETE
some_one@so: INCOMPLETE
some_one@som: INCOMPLETE
some_one@some: INCOMPLETE
some_one@somem: INCOMPLETE
some_one@somema: INCOMPLETE
some_one@somemai: INCOMPLETE
some_one@somemail: INCOMPLETE
some_one@somemail.: INCOMPLETE
some_one@somemail.c: VALID
some_one@somemail.co: VALID
some_one@somemail.com: VALID
@: INVALID
@d: INVALID
@do: INVALID
@dom: INVALID
@doma: INVALID
@domai: INVALID
@domain: INVALID
@domain.: INVALID
@domain.n: INVALID
@domain.na: INVALID
@domain.nam: INVALID
@domain.name: INVALID
Таким образом, для определенных входных данных мы можем рано определить, что ввод будет оставаться недействительным, когда вводится только вперед, тогда как другие, например eshaka@horm
, могут считаться недействительными только тогда, когда мы говорим, что они должны быть завершены.
Вы также можете использовать эту функцию, чтобы найти проблему:
static void feedback(CharSequence input) {
System.out.append(input).append(": ");
Matcher matcher = VALID_MAIL.matcher(input);
if(matcher.matches()) System.out.println("Ok");
else if(matcher.hitEnd()) System.out.println("Type ahead");
else {
for(int p = 0; p < input.length(); p++)
if(!matcher.region(0, p).matches() && !matcher.hitEnd()) {
System.out.println("(First) problem at position "+p);
break;
}
}
}
for(String input: samples) feedback(input);
eshaka@horm: Type ahead
some_one@some@ma: (First) problem at position 14
some_one@somemail.com: Ok
@domain.name: (First) problem at position 1