Java 使用星型字符搜索文本的正则表达式

Java 使用星型字符搜索文本的正则表达式,java,regex,search,filter,Java,Regex,Search,Filter,我正在编写一个Java应用程序,其中用户可以根据用户提供的过滤器减少字符串列表 例如,用户可以输入一个过滤器,例如: ABC*xyz 这意味着用户正在查找以ABC开头且后面有xyz的字符串(这与搜索ABC*xyz*) 用户可以输入的过滤器的另一个示例是: *DEF*mno*rst 这意味着字符串可以以任何内容开头,但随后必须以DEF、mno和rst开头 如何编写Java代码来生成正则表达式,以确定我的字符串是否与用户指定的筛选器匹配?将*替换为*,您就有了正则表达式 String str

我正在编写一个Java应用程序,其中用户可以根据用户提供的过滤器减少字符串列表

例如,用户可以输入一个过滤器,例如:

 ABC*xyz
这意味着用户正在查找以ABC开头且后面有xyz的字符串(这与搜索
ABC*xyz*

用户可以输入的过滤器的另一个示例是:

 *DEF*mno*rst
这意味着字符串可以以任何内容开头,但随后必须以DEF、mno和rst开头


如何编写Java代码来生成正则表达式,以确定我的字符串是否与用户指定的筛选器匹配?

*
替换为
*
,您就有了正则表达式

String str = "*DEF*mno*rst";
String regex = str.replaceAll("*", ".*");

如果将语法转换为regex,这是一种“简单”的方法(避免自己编写lexer),那么必须记住适当地转义字符串

因此,如果沿着这条路线走下去,您可能应该在语法中引用非通配符的位,并加入regex
*
(或者
+
,如果您希望
*
表示“至少一个字符”。这将避免在使用
*
)时出现错误的结果
和所有其他正则表达式特殊字符

尝试以下方法:

public Pattern createPatternFromSearch(String query) {
    StringBuilder sb = new StringBuilder();
    for (String part : query.split("\\*")) {
        if (part.length() > 0) {
            sb.append(Pattern.quote(part));
        }
        sb.append(".*");
    }
    return Pattern.compile(sb.toString());
}

// ...

// then you can use it like....
Matcher matcher = createPatternFromQuery("*DEF*mno*rst").matcher(str);
if (matcher.matches()) {
   // process the matching result
}

请注意,通过使用(而不是
find
)并保留尾随的
*
,它将满足仅在开头锚定的语法。

看一看
*
将转换为
*
ABC*xyz
->
ABC.*xyz
)那么问题出在哪里呢?不,这在一般情况下不起作用:它不只是在开头锚定,也不处理任何特殊的正则表达式字符(
*
我同意@Nick B。我们可能希望转义特殊的正则字符,这会使它有点复杂。在这个解决方案中没有
\*
序列(除了文字序列,不会被误解-这不是工作方式)。