Соответствие строки Java с подстановочными знаками
У меня есть строка шаблона с подстановочным знаком, скажем, X (например, abc*).
Также у меня есть набор строк, которые я должен сопоставить с данным шаблоном.
Например:
abf - ложь
abc_fgh - правда
abcgafa - правда
фгабчафа - ложь
Я попытался использовать регулярные выражения для того же, это не сработало.
Вот мой код
String pattern = "abc*";
String str = "abcdef";
Pattern regex = Pattern.compile(pattern);
return regex.matcher(str).matches();
Это возвращает ложь
Есть ли другой способ сделать эту работу?
Спасибо
5 ответов
Просто используйте шаблон стиля bash для преобразования шаблона стиля Java:
public static void main(String[] args) {
String patternString = createRegexFromGlob("abc*");
List<String> list = Arrays.asList("abf", "abc_fgh", "abcgafa", "fgabcafa");
list.forEach(it -> System.out.println(it.matches(patternString)));
}
private static String createRegexFromGlob(String glob) {
StringBuilder out = new StringBuilder("^");
for(int i = 0; i < glob.length(); ++i) {
final char c = glob.charAt(i);
switch(c) {
case '*': out.append(".*"); break;
case '?': out.append('.'); break;
case '.': out.append("\\."); break;
case '\\': out.append("\\\\"); break;
default: out.append(c);
}
}
out.append('$');
return out.toString();
}
Есть ли эквивалент java.util.regex для шаблонов типа "glob"?
Преобразовать подстановочный знак в выражение регулярного выражения
abc*
будет RegEx, который соответствует ab
, abc
, abcc
, abccc
и так далее.
Что вы хотите abc.*
- если abc
предполагается, что это начало совпадающей строки, и это необязательно, если что-либо следует за ним.
В противном случае вы можете подготовить .*
также сопоставлять строки с abc
в середине: .*abc.*
Обычно я рекомендую поиграть с таким сайтом, чтобы изучить RegEx. Вы просите довольно простой шаблон, но трудно сказать, что именно вам нужно. Удачи!
РЕДАКТИРОВАТЬ:
Похоже, вы хотите, чтобы пользователь вводил часть имени файла (или около того), и вы хотите предложить что-то вроде функции поиска (вы могли бы сделать это ясно в своем вопросе IMO). В этом случае вы можете испечь свой собственный RegEx из пользовательского ввода:
private Pattern getSearchRegEx(String userInput){
return Pattern.compile(".*" + userInput + ".*");
}
Конечно, это очень простой пример. Вы можете изменить это, а затем использовать RegEx для сопоставления имен файлов.
Итак, я думаю, вот ваш ответ: регулярное выражение, которое вы ищете, это: [a][b][c].*
Вот мой код, который работает:
String first = "abc"; // true
String second = "abctest"; // true
String third = "sthabcsth"; // false
Pattern pattern = Pattern.compile("[a][b][c].*");
System.out.println(first.matches(pattern.pattern())); // true
System.out.println(second.matches(pattern.pattern())); // true
System.out.println(third.matches(pattern.pattern())); // false
Но если вы хотите проверить, только начинается или заканчивается, вы можете использовать методы String
: .startsWith()
а также endsWith()
// The main function that checks if two given strings match. The pattern string may contain
// wildcard characters
default boolean matchPattern(String pattern, String str) {
// If we reach at the end of both strings, we are done
if (pattern.length() == 0 && str.length() == 0) return true;
// Make sure that the characters after '*' are present in str string. This function assumes that
// the pattern string will not contain two consecutive '*'
if (pattern.length() > 1 && pattern.charAt(0) == '*' && str.length() == 0) return false;
// If the pattern string contains '?', or current characters of both strings match
if ((pattern.length() > 1 && pattern.charAt(0) == '?')
|| (pattern.length() != 0 && str.length() != 0 && pattern.charAt(0) == str.charAt(0)))
return matchPattern(pattern.substring(1), str.substring(1));
// If there is *, then there are two possibilities
// a: We consider current character of str string
// b: We ignore current character of str string.
if (pattern.length() > 0 && pattern.charAt(0) == '*')
return matchPattern(pattern.substring(1), str) || matchPattern(pattern, str.substring(1));
return false;
}
public static void main(String[] args) {
test("w*ks", "weeks"); // Yes
test("we?k*", "weekend"); // Yes
test("g*k", "gee"); // No because 'k' is not in second
test("*pqrs", "pqrst"); // No because 't' is not in first
test("abc*bcd", "abcdhghgbcd"); // Yes
test("abc*c?d", "abcd"); // No because second must have 2 instances of 'c'
test("*c*d", "abcd"); // Yes
test("*?c*d", "abcd"); // Yes
}