#java #regex
Вопрос:
Я ищу способ сопоставить список параметров, которые включают некоторые предопределенные символы и некоторые переменные символы, используя String#matches
метод Java. Например:
Возможный параметр 1: abc;[variable lowercase letters with maybe an underscore]
Возможный Параметр 2: cde;[variable lowercase letters with maybe an underscore]
Возможный параметр 3: g;4
Пример 1: abc;erga_sd,cde;dfgef,g;4
Пример 2: g;4,abc;dsfaweg
Пример 3: cde;df_ger
Каждый из параметров будет разделен запятыми, но они могут располагаться в любом порядке и включать 1, 2 и/или 3 (без дубликатов).
Это регулярное выражение, которое у меня есть до сих пор, частично работает: (abc;[a-z_,] ){0,1}|(cde;[a-z,] ){0,1}|(g;4,){0,1}
Проблема в том, что он также находит что-то вроде этого допустимым: abc;dsfg,dfvser
где начало строки после запятой не начинается с допустимого abc;
или cde;
или g;4
Комментарии:
1. Почему вы думаете, что регулярное выражение-это инструмент, который вам нужен?
Ответ №1:
Как вы сказали:
Проблема в том,что он также находит что-то вроде этого допустимого: abc;dsfg, dfvser, где начало строки после запятой не начинается с допустимого abc; или cde; или g;4
Поэтому допустимые записи всегда будут иметь шаблоны после запятой. Что вы можете сделать, так это разделить все входные данные разделителем ","
и применить допустимый шаблон регулярного выражения к разделенным элементам, а затем объединить результаты сопоставления разделенных элементов, чтобы получить результат сопоставления всей входной строки.
Ваше регулярное выражение должно быть:
(abc;[a-z_] )|(cde;[a-z_] )|(g;4)
Вы получите любой из этих трех шаблонов, как вы упоминали в своем посте ранее, в допустимом элементе, который вы получили, выполнив разделение в строке ввода.
Вот код:
String regex = "(abc;[a-z_] )|(cde;[a-z_] )|(g;4)";
boolean finalResult = true;
for (String input: inputList.split(",")) {
finalResult = finalResult amp;amp; Pattern.matches(regex,input);
}
System.out.println(finalResult);
Ответ №2:
Если вы хотите использовать совпадения, то вся строка должна совпадать.
^(?:(?:abc|cde);[a-z_] |g;4)(?:,(?:(?:abc|cde);[a-z_] |g;4))*$
Объяснение
^
Начало строки(?:
Группа без захвата(?:abc|cde);[a-z_]
совпадение илиabc;
илиcde;
и 1 символов a-z или_
|
Илиg;4
Совпадение буквально
)
Закрыть группу без захвата(?:
Группа без захвата,(?:(?:abc|cde);[a-z_] |g;4)
Поставьте запятую и повторите первый шаблон
)*
Закройте группу без захвата и при необходимости повторите$
Конец строки
Смотрите демонстрацию регулярных выражений и демонстрацию Java
Пример кода
String[] strings = {
"abc;erga_sd,cde;dfgef,g;4",
"g;4,abc;dsfaweg",
"cde;df_ger",
"g;4",
"abc;dsfg,dfvser"
};
String regex = "^(?:(?:abc|cde);[a-z_] |g;4)(?:,(?:(?:abc|cde);[a-z_] |g;4))*$";
Pattern pattern = Pattern.compile(regex);
for (String s : strings) {
Matcher matcher = pattern.matcher(s);
if (matcher.matches()) {
System.out.printf("Match for %s%n", s);
} else {
System.out.printf("No match for %s%n", s);
}
}
Выход
Match for abc;erga_sd,cde;dfgef,g;4
Match for g;4,abc;dsfaweg
Match for cde;df_ger
Match for g;4
No match for abc;dsfg,dfvser
Если не должно быть никакого дубликата abc;
cde
, или g;4
вы можете исключить это, используя отрицательный внешний вид с обратной ссылкой, чтобы дважды соответствовать одному и тому же в начале шаблона.
^(?!.*(abc;|cde;|g;4).*1)(?:(?:abc|cde);[a-z_] |g;4)(?:,(?:(?:abc|cde);[a-z_] |g;4))*$