Java 带通配符的字符串匹配
Java string matching with wildcards
我有一个带有通配符 X 的模式字符串(例如:abc*)。
我还有一组字符串,我必须根据给定的模式进行匹配。
例如:
abf-假
abc_fgh - 真
abcgafa - 正确
fgabcafa - 错误
我试过使用正则表达式,但没有用。
这是我的代码
String pattern = "abc*";
String str = "abcdef";
Pattern regex = Pattern.compile(pattern);
return regex.matcher(str).matches();
这个returns假
还有其他方法可以实现吗?
谢谢
abc*
将是匹配 ab
、abc
、abcc
、abccc
等的正则表达式。
你想要的是 abc.*
- 如果 abc
应该是匹配字符串的开头,如果后面有任何内容,它是可选的。
否则,您可以在前面添加 .*
以匹配中间带有 abc
的字符串:.*abc.*
一般来说,我建议使用像 this 这样的网站来学习 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()
只需使用 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();
}
Is there an equivalent of java.util.regex for “glob” type patterns?
Convert wildcard to a regex expression
您可以使用 stringVariable.startsWith("abc")
// 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
}
我有一个带有通配符 X 的模式字符串(例如:abc*)。
我还有一组字符串,我必须根据给定的模式进行匹配。
例如:
abf-假
abc_fgh - 真
abcgafa - 正确
fgabcafa - 错误
我试过使用正则表达式,但没有用。
这是我的代码
String pattern = "abc*";
String str = "abcdef";
Pattern regex = Pattern.compile(pattern);
return regex.matcher(str).matches();
这个returns假
还有其他方法可以实现吗?
谢谢
abc*
将是匹配 ab
、abc
、abcc
、abccc
等的正则表达式。
你想要的是 abc.*
- 如果 abc
应该是匹配字符串的开头,如果后面有任何内容,它是可选的。
否则,您可以在前面添加 .*
以匹配中间带有 abc
的字符串:.*abc.*
一般来说,我建议使用像 this 这样的网站来学习 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()
只需使用 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();
}
Is there an equivalent of java.util.regex for “glob” type patterns?
Convert wildcard to a regex expression
您可以使用 stringVariable.startsWith("abc")
// 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
}