Я пытаюсь использовать Java Pattern и Matcher для проверки ввода. У меня он работает в действительно базовом формате, которым я пока доволен. Он применяет REGEX к аргументу, а затем перебирает совпадающие символы.
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexUtil {
public static void main(String[] args) {
String argument;
Pattern pattern;
Matcher matcher;
argument = "#a1^b2";
pattern = Pattern.compile("[a-zA-Z]|[0-9]|\\s");
matcher = pattern.matcher(argument);
// find all matching characters
while(matcher.find()) {
System.out.println(matcher.group());
}
}
}
Это нормально для извлечения всех хороших символов, я получаю вывод
a
1
b
2
Теперь я хотел узнать, можно ли сделать то же самое для любых символов, которые не соответствуют REGEX, поэтому я получаю результат
#
^
Или еще лучше прокрутите его и получите флаги TRUE или FALSE для каждого индекса аргумента
false
true
true
false
true
true
Я знаю только, как выполнить цикл с помощью matcher.find (), любая помощь будет принята с благодарностью




Вам нужно перебрать каждый char из String и проверить один за другим:
//for-each loop, shorter way
for (char c : argument.toCharArray()){
System.out.println(pattern.matcher(c + "").matches());
}
или же
//classic for-i loop, with details
for (int i = 0; i < argument.length(); i++) {
String charAtI = argument.charAt(i) + "";
boolean doesMatch = pattern.matcher(charAtI).matches();
System.out.println(doesMatch);
}
Кроме того, если вам это не нужно, вы можете объявить и указать значение одновременно:
String argument = "#a1^b2";
Pattern pattern = Pattern.compile("[a-zA-Z]|[0-9]|\\s");
Вы можете добавить альтернативу |(.) к своему шаблону (чтобы соответствовать любому символу, кроме символа разрыва строки) и проверять, соответствует ли Группа 1 при каждом совпадении. Если да, выведите ложный, иначе выведите правда:
String argument = "#a1^b2";
Pattern pattern = Pattern.compile("[a-zA-Z]|[0-9]|\\s|(.)"); // or "[a-zA-Z0-9\\s]|(.)"
Matcher matcher = pattern.matcher(argument);
while(matcher.find()) { // find all matching characters
System.out.println(matcher.group(1) == null);
Смотрите Демонстрация Java, вывод:
false
true
true
false
true
true
Обратите внимание, что здесь вам не нужно использовать Pattern.DOTALL, потому что \s в вашем «белом списке» части шаблона соответствует разрывам строк.
Условие проверки для вывода логического значения можно упростить как базовый while (matcher.find()) { System.out.println(matcher.group(1) == null); }.
@azro Да, я просто подумал, что может потребоваться настраиваемая строка, если нужны только значения true или false, тогда конечно.
Мне очень нравится этот ответ, но у меня есть вопрос о группе. Если я создам две группы "([a-zA-Z] | [0-9] | \\ s) | (.)" Для ясности, то почему matcher.group (2) не дает мне каждый символ в цикле?
@Trent Потому что Группа 1 будет их держать. Регулярное выражение в основном разбивает строку на два типа символов: те, которые вы хотите пометить как правда, и те, которые должны быть ложный.
Хорошо, так что все, что соответствует группе 1, не может совпадать дважды и не совпадать с группой 2?
@ Трент Извини, я тебя не понимаю. Если вы просто хотите распечатать совпадение, распечатайте его с помощью matcher.group(0).
Ничего страшного, я должен немного повозиться, но этот ответ идеально подходит для того, что мне нужно, большое спасибо
Почему бы просто не удалить все совпадающие символы из вашей строки, чтобы вы вернули только несоответствующие:
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class RegexUtil {
public static void main(String[] args) {
String argument;
Pattern pattern;
Matcher matcher;
argument = "#a1^b2";
pattern = Pattern.compile("[a-zA-Z]|[0-9]|\\s");
matcher = pattern.matcher(argument);
// find all matching characters
while(matcher.find()) {
System.out.println(matcher.group());
argument = argument.replace(matcher.group(), "");
}
System.out.println("argument: " + argument);
}
}
Отслеживайте позиции и для каждого совпадения выводите символы между последним совпадением и текущим совпадением.
int pos = 0;
while (matcher.find()) {
for (int i = pos; i < matcher.start(); i++) {
System.out.println(argument.charAt(i));
}
pos = matcher.end();
}
// Print any trailing characters after last match.
for (int i = pos; i < argument.length(); i++) {
System.out.println(argument.charAt(i));
}
Одно из решений
String argument;
Pattern pattern;
Matcher matcher;
argument = "#a1^b2";
List<String> charList = Arrays.asList(argument.split(""));
pattern = Pattern.compile("[a-zA-Z]|[0-9]|\\s");
matcher = pattern.matcher(argument);
ArrayList<String> unmatchedCharList = new ArrayList<>();
// find all matching
while(matcher.find()) {
unmatchedCharList.add(matcher.group());
}
for(String charr : charList)
{
System.out.println(unmatchedCharList.contains(charr ));
}
Выход
ложный правда правда ложный правда правда
[^a-zA-Z0-9]выдаст вам все символы, не соответствующие диапазону, поэтому: # ^