匹配正则表达式三个字搜索java

时间:2016-07-18 12:19:36

标签: java regex matcher

我有两个符号字符串查询搜索算法。我有一个由逗号分隔的三个单词组成的字符串。我想要的是在这三个prarms之间进行搜索。

例如"字符串,文字,搜索"

如果输入是" Te"搜索应该匹配,也" Str"," Se"应该匹配。

我使用正则表达式实现。但它只适用于第一个单词。请注意,我在第二个单词之前有一个空格。

        stringInput="String, Text,Search";
        word="St";
        String pattern1=word+"\\w*,\\s\\w*,\\w";

        String pattern2="\\w*,\\."+word+"\\w*,\\w";

        String pattern3="\\w*,\\w*,"+word+"\\w";

        Pattern patternCompiled1=Pattern.compile(pattern1);
        Pattern patternCompiled2=Pattern.compile(pattern2);
        Pattern patternCompiled3=Pattern.compile(pattern3);
        Matcher matcher1= patternCompiled1.matcher(inputString);

        Matcher matcher2= patternCompiled2.matcher(inputString);

        Matcher matcher3= patternCompiled3.matcher(inputString);

            if(matcher1.find() || matcher2.find() || matcher3.find()){
                return true;
            }

你能帮我解释为什么它不能用于第二个和第三个词吗?

一些澄清

Word1,String1,String2 第一个参数总是只有一个单词,第二个参数可以是两个或多个单词,第三个参数可以是两个 - 它可以是由空格分隔的几个单词。 例如。文本,一些文本,其他文本文本它可以是任何文本,一些,其他文本 它也可以包含不同的符号,我想要的是使搜索匹配每个参数的第一个单词的第一个字母。

2 个答案:

答案 0 :(得分:4)

您的模式不正确。我强烈建议你学习更多关于正则表达式的知识:

您的第一个模式:word+"\\w*,\\s\\w*,\\w"匹配:

  • 要匹配的字符串
  • 后跟0个或更多单词字符
  • 后跟逗号
  • 后跟一个空格字符
  • 后跟0个或更多单词字符
  • 后跟逗号
  • 后跟一个单词字符

此模式适用于给定的输入字符串,但如果在最后一个逗号后面有空格则会失败。

第二种模式:"\\w*,\\."+word+"\\w*,\\w"匹配:

  • 0个或更多单词字符
  • 后跟逗号
  • 后面是文字。
  • 后面跟着匹配的字符串
  • 后跟0个或更多单词字符
  • 后跟逗号
  • 后跟一个单词字符

这不起作用,因为您已转义.字符\\.,这意味着它将匹配您的字符串不包含的文字.

您的最终模式:"\\w*,\\w*,"+word+"\\w"匹配:

  • 0个或更多单词字符
  • 后跟逗号
  • 后跟0个或更多单词字符
  • 后跟逗号
  • 后面跟着匹配的字符串
  • 后跟一个单词字符

这会失败,因为您没有在逗号后面占空格。

单个正确的正则表达式模式类似于:

^(?:%s.*,.*,.*)|(?:.*,\\s*%s.*,.*)|(?:.*,.*,\\s*%s.*)$

%s是您要搜索的字符串。

说明:

  • ^匹配字符串的开头,$匹配字符串的结尾。
  • 有三个非捕获组(?:)
  • 每个组由|分隔,表示或。所以这些组中只有一个需要匹配。
  • 第一组是匹配第一个单词开头的搜索文本,所以简单地说,搜索文本后跟0或更多任何字符,后跟逗号,后跟0或更多任何字符...
  • 第二组是匹配第二个单词开头的搜索文本,这类似于第一个模式,除了我们只想匹配第二个单词之前的空格而不是任何字符。
  • 第三组是匹配第三个单词开头的搜索文本,这个模式与第二个单词几乎相同,只是向右移动。

用法:

String pattern = String.format("^(?:%s.*,.*,.*)|(?:.*,\\s*%s.*,.*)|(?:.*,.*,\\s*%s.*)$", 
            searchText, searchText, searchText);

Matcher m = Pattern.compile(pattern).matcher(stringInput);
System.out.println(m.find());

但是,有一个更简单的解决方案,无需复杂的正则表达式模式。

替代解决方案(拆分为单词并检查是否以搜索文本开头):

private boolean anyWordStartsWith(final String words, final String search) {
    for (final String word : words.split("\\s*,\\s*")) {
        if(word.startsWith(search)) return true;
    }
    return false;
}

替代解决方案(Java 8):

boolean anyMatch = Arrays.stream(stringInput.split("\\s*,\\s*"))
                         .anyMatch(word -> word.startsWith(searchText));

答案 1 :(得分:0)

对于pattern2\\.将与点字符匹配,但此时没有点(您可能只想使用不带\\的点来匹配任何角色)

对于pattern3,您忘记了相同的点(或\\s中使用的pattern1)。

所以这应该是这样的:

String pattern1=word+"\\w*,\\s\\w*,\\w";
String pattern2="\\w*,."+word+"\\w*,\\w"; // Or replace dot with \\s
String pattern3="\\w*,.\\w*,"+word+"\\w"; //Same here

如果您希望它与stringInput="String, Text,Search";

一起使用