Java 文本查询匹配(棘手)

Java 文本查询匹配(棘手),java,regex,string,match,Java,Regex,String,Match,我在大学里参加了一个微软编码挑战赛,问的问题是: 编写一个以两个字符串作为输入的程序,一个是查询,另一个是可能包含或不包含该查询的字符串。程序需要查找查询是否包含在正文字符串中 1) 如果查询与正文文本中某个单词的开头匹配,则该查询应仅与正文文本匹配 2) 也就是说,查询的开头也必须是正文中某个单词的开头。例如,查询“cat”将匹配字符串“cat”、“cat toy”、“this a cat”和“catty”。但是,查询“cat”与字符串“location”不匹配 3) 你的程序应该不区分大小写

我在大学里参加了一个微软编码挑战赛,问的问题是:

编写一个以两个字符串作为输入的程序,一个是查询,另一个是可能包含或不包含该查询的字符串。程序需要查找查询是否包含在正文字符串中

1) 如果查询与正文文本中某个单词的开头匹配,则该查询应仅与正文文本匹配

2) 也就是说,查询的开头也必须是正文中某个单词的开头。例如,查询“cat”将匹配字符串“cat”、“cat toy”、“this a cat”和“catty”。但是,查询“cat”与字符串“location”不匹配

3) 你的程序应该不区分大小写

4) 您的程序需要能够匹配没有空格的查询,即使主体中确实有空格。例如,字符串“Luke Johnston”将由查询“Luke j”和查询“lukej”匹配

5) 然而,这并不是反过来的。查询“luke j”不应与字符串“lukejohnston”匹配

我能够编写满足前4个要求的代码,但我无法找到第5个要求的解决方案。任何提示/帮助都将不胜感激。这是我的代码版本

package regex;

import java.util.Scanner;

public class TextQueryMatch {
public static void main(String[] args){
    Scanner in = new Scanner(System.in);
    System.out.print("Enter the Text: ");
    String text = in.nextLine();
    text = text.toLowerCase();
    String[] substexts = text.split("\\s");
    text = "";
    for(int i = 0; i < substexts.length; i++){
        char capLetter = Character.toUpperCase(substexts[i].charAt(0));
        text += capLetter + substexts[i].substring(1, substexts[i].length());
    }
    System.out.println(text);
    System.out.print("Enter the Query: ");
    String query = in.nextLine();
    query = query.toLowerCase();
    String[] subquerys = query.split("\\s");
    query = "";
    for(int i = 0; i < subquerys.length; i++){
        char capLetter = Character.toUpperCase(subquerys[i].charAt(0));
        query += capLetter + subquerys[i].substring(1, subquerys[i].length());
    }
    System.out.println(query);
    System.out.print("Match: ");
    if(text.matches("(.*)"+query.charAt(0)+"(.*)")){
        text=text.toLowerCase();
        query=query.toLowerCase();
        System.out.print(text.matches("(.*)"+query+"(.*)"));
    }else{
        System.out.print("False");
    }
}
}
package正则表达式;
导入java.util.Scanner;
公共类TextQueryMatch{
公共静态void main(字符串[]args){
扫描仪输入=新扫描仪(系统输入);
System.out.print(“输入文本:”);
字符串text=in.nextLine();
text=text.toLowerCase();
String[]subtexts=text.split(\\s”);
text=“”;
for(int i=0;i
尝试使用以下方法:

public static boolean match(String text, String query) {
    text = text.toLowerCase();
    query = query.toLowerCase();

    String noSpaces = text.replaceAll(" ", "");
    String[] tWords = text.split(" ");

    if (text.startsWith(query) || noSpaces.startsWith(query)) {
        return true;
    }

    for (int i = 0; i < tWords.length; i++) {
        if (tWords[i].startsWith(query)) {
            return true;
        }
    }

    return false;
}
公共静态布尔匹配(字符串文本、字符串查询){
text=text.toLowerCase();
query=query.toLowerCase();
字符串noSpaces=text.replaceAll(“,”);
字符串[]tWords=text.split(“”);
if(text.startsWith(查询)| | noSpaces.startsWith(查询)){
返回true;
}
for(int i=0;i
我认为将查询转换为正则表达式就足以满足所有给定条件

根据问题,

根据第1点和第2点,仅当查询字符串位于文本开头或空格后,查询才应与文本匹配。基本上,这个的正则表达式是这样的-

(^|\s)(query-string)
第3点需要查询不区分大小写,这可以在编译查询正则表达式时处理

对于第4点和第5点-即使查询没有空格,查询也应与文本匹配,但如果查询中存在空格,则应在文本中正确匹配

因此,我们需要以这样的方式转换正则表达式,在每个字符(或空格)之后,正则表达式可以处理可能存在或不存在的空格。这样,我们假设字符(或空格)必须匹配,而后面的空格是有条件的

这应该行得通-

 public static boolean find_match(String query, String text){
    String regex = "(?:^|\\s)(" + query.replaceAll(".(?!$)", "$0(?:\\\\s*)") + ")";
    //System.out.println("Regex -> " + regex);
    Pattern re = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);    
    return re.matcher(text).find();
 }
测试此功能-

public static void main(String []args){        
    String query1 = "cat";
    String[] text1 = {
        "Cat",
        "caT toy",
        "This is a CaT",
        "caTty",
        "loCation"
    };
    for(String s : text1){
        System.out.println("Query -> " + query1 + "\nText -> " + s + "\n" + find_match(query1, s) + "\n");
    }
    String query2 = "luke j";
    String query3 = "lukej";
    String[] text2 = {
        "Luke Johnson",
        "lukejohnson",
        "Luke      Johson",
        "This is Luke  Johnson",
        "L ukeJohnson",
        "L uke Johnson"
    };
    for(String s : text2){
        System.out.println("Query -> " + query2 + "\nText -> " + s + "\n" + find_match(query2, s));
        System.out.println("Query -> " + query3 + "\nText -> " + s + "\n" + find_match(query3, s) + "\n");
    }    
 }
输出->

Query -> cat
Text -> Cat
true

Query -> cat
Text -> caT toy
true

Query -> cat
Text -> This is a CaT
true

Query -> cat
Text -> caTty
true

Query -> cat
Text -> loCation
false

Query -> luke j
Text -> Luke Johnson
true
Query -> lukej
Text -> Luke Johnson
true

Query -> luke j
Text -> lukejohnson
false
Query -> lukej
Text -> lukejohnson
true

Query -> luke j
Text -> Luke      Johson
true
Query -> lukej
Text -> Luke      Johson
true

Query -> luke j
Text -> This is Luke  Johnson
true
Query -> lukej
Text -> This is Luke  Johnson
true

Query -> luke j
Text -> L ukeJohnson
false
Query -> lukej
Text -> L ukeJohnson
true

Query -> luke j
Text -> L uke Johnson
true
Query -> lukej
Text -> L uke Johnson
true

希望这有助于-

有许多可能的情况可以确定您的查询是否包含在正文中。让我们来解释一下你在问题中给出的猫和另一个身体字符串样本

您的查询将具有以下版本:- 例如当猫在句子之间时 :以cat结尾或后跟、或的句子。或任何符号(您可能希望使用ASCII检查后面的字符) :当句子以cat开头时。 :正文是单字句子,您可以使用大小功能进行确认。 _被称为空间


首先,您需要将整个正文和查询字符串转换为小写或大写(或者不转换,因为没有指定匹配操作是否区分大小写)

这是一个很好的解决方案,但如果我传递text=“A Luke Johnston”和query=“Luke j”,则会失败,因为在for循环中,当i=2时,它将失败,因为它将约翰斯顿与卢克j进行比较。它起到了帮助作用。请你详细说明一下regex声明好吗。对于query=“luke j”,它给出正则表达式=(?:^\s)(l(?:\s*)u(?:\s*)k(?:\s*)e(?:\s*)(?:\s*)j)。我不熟悉使用正则表达式,正在引用,但找不到一些符号。分组符号,()和(?:)是捕获组和非捕获组。转介他们。对于其余的符号,如果您想从头开始正确地使用正则表达式,那么使用教程是相当全面的