我在大学参加了Microsoft编码挑战,这是一个问题:


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

1)查询仅应与正文中的单词开头匹配的正文。

2)也就是说,查询的开头也必须是正文中单词的开头。例如,查询“ cat”将匹配字符串“ cat”,“ cat toy”,“ this is 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");
    }
}
}

最佳答案

我认为将查询转换为正则表达式就可以满足所有给定条件。

根据问题,

在第1点和第2点,仅当查询字符串位于文本开头或后接空格时,查询才应与文本匹配。因此,基本上,正则表达式如下所示:

(^|\s)(query-string)


第三点要求查询不区分大小写,可以在编译查询正则表达式时进行处理。

对于第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


希望这可以帮助-

07-24 17:58