Java中的嘈杂字符串匹配?

时间:2014-04-15 22:33:00

标签: java string pattern-matching substring

考虑以下字符串:

Arg =“north_carolina_state_university”

Text =“哈克尼在转学到北卡罗来纳大学教堂山分校之前就读于北卡罗来纳州立大学,在那里他获得了学士学位和法学博士学位。他从1971年至1974年担任检察官,然后进入私人执业。1974年他是国会议员艾克·安德鲁斯(Ike Andrews)的竞选经理。在UNC-Chapel Hill的本科生期间,他撰写了关于北卡罗来纳州惩戒系统历史的荣誉论文。“

我知道在文本中可以找到Arg的变体,但不一定相同,Arg可能会很吵。

另一个例子如下:

Arg2 =“maurice_blackburn”

Text2 =“Maurice McCrae Blackburn(1880年11月19日 - 1944年3月31日),澳大利亚政治家和律师,出生于维多利亚州的英格尔伍德。他在1887年父亲去世后随母亲搬到墨尔本。他是1896年在墨尔本文法学校接受教育。完成学业后,他进入墨尔本大学,1909年毕业于艺术和法律专业,一年后开始从事律师工作。“

在上面的例子中,在Text2中没有使用Arg2中的中间名。

Arg3 =“kansas_city_metropolitan_area” Text3 =“罗奇当选为第六十七届和第六十八届大会的共和党人(1921年3月4日至1925年3月3日)。他曾担任司法部支出委员会主席(第六十八届大会)他是1924年第六十九届国会蝉联连任的不成功候选人。他于1924年12月27日移居密苏里州圣路易斯,并恢复了法律实践。他于6月29日在密苏里州堪萨斯城去世,他被密苏里州罗奇附近的罗奇公墓埋葬了。“

在这个例子中,“堪萨斯城”出现在Text3中,但没有“都市区”(因为它出现在Arg3中)。

任何用于发现文本中Arg出现的函数/库?

2 个答案:

答案 0 :(得分:2)

我希望这个答案可以帮助你至少得到一些想法。我创建了一个方法来回答这个问题

  

任何用于发现文本中Arg出现的函数/库?

以下是我使用上述示例从我的方法收到的以下输出:

  

Arg =“north_carolina_state_university”

     

Text =“哈克尼之前就读过北卡罗来纳州立大学   转移到北卡罗来纳大学教堂山分校   他获得了学士学位和法学博士学位。他的工作是一个   检察官从1971年至1974年进入私人执业。 1974年   他是国会议员艾克安德鲁斯的竞选经理。而一个   在UNC-Chapel Hill的本科生,他写了他的荣誉论文   北卡罗来纳州惩戒系统的历史。“

     

输出

     

匹配结果

     

词:4/4

     

快报:28/28

     
     

Arg2 =“maurice_blackburn”

     

Text2 =“Maurice McCrae Blackburn(1880年11月19日 - 1944年3月31日),   澳大利亚政治家和律师,出生于维多利亚州的英格尔伍德。他   在父亲去世后,他的母亲搬到了墨尔本   他于1887年在墨尔本文法学校接受教育   完成学业后,他于1909年就读于墨尔本大学,毕业于艺术与法律专业,并开始从事实践   一年后成为一名律师。“

     

<强>输出

     

匹配结果

     

词:2/2

     

快报:16/16

     
     

Arg3 =“kansas_city_metropolitan_area”

     

Text3 =“罗奇当选为   共和党参加第六十七届和第六十八届大会(3月4日,   1921年 - 1925年3月3日)。他担任委员会主席   司法部的支出(第六十八届大会)。他   是一个不成功的候选人,在1924年连任   第六十九届大会。他于12月27日搬到密苏里州的圣路易斯,   1924年,恢复了法律实践。他在堪萨斯城去世,   密苏里州,1934年6月29日。他被埋葬在罗奇附近的罗奇公墓,   密苏里”。

     

<强>输出

     

匹配结果

     

词:2/4

     

快报:13/26

此方法仅搜索英文字母字母,仅搜索单词(空格分隔),它也不会按顺序搜索单词字母。如果您搜索cat和某人类型acat,它将显示为不匹配,也不会显示为任何字母匹配。这是因为狗不是热狗。你真的必须决定你想要比赛的模糊程度。这段代码绝不是最好的,但我希望它可以给你一些想法,也许可以重写它更整洁有序。无论哪种方式,它确实回答了你提出的确切问题。

public static String search(String search, String target) {
        String result = "";
        search = search.toLowerCase();
        target = target.toLowerCase();
        StringBuilder temp = new StringBuilder();
        ArrayList<String> searchWords = new ArrayList<String>();
        ArrayList<String> targetWords = new ArrayList<String>();
        char lastChar = ' ';
        char currentChar = ' ';
        // search,text
        int swords, twords, sletters, tletters, mwords, mletters;
        swords = twords = sletters = tletters = mwords = mletters = 0;

        for (Character c : search.toCharArray()) {
        currentChar = c > 96 && c < 123 ? c : ' ';
        if (lastChar == ' ' && currentChar == ' ')
            continue;
        if (currentChar != ' ' && ++sletters != 0)
            temp.append(currentChar);
        else {
            searchWords.add(temp.toString());
            temp.setLength(0);
        }
        lastChar = currentChar;
        }
        searchWords.add(temp.toString());
        temp.setLength(0);
        lastChar = ' ';
        for (Character c : target.toCharArray()) {
        currentChar = c > 96 && c < 123 ? c : ' ';
        if (lastChar == ' ' && currentChar == ' ')
            continue;
        if (currentChar != ' ' && ++tletters != 0)
            temp.append(currentChar);
        else {
            targetWords.add(temp.toString());
            temp.setLength(0);
        }
        lastChar = currentChar;
        }
        targetWords.add(temp.toString());
        temp.setLength(0);
        search = searchWords.toString();
        target = targetWords.toString();
        swords = searchWords.size();
        twords = targetWords.size();
        int[] blm = new int[searchWords.size()]; // best letter match
        int lm = 0;// letter match
        for (int i = 0; i < searchWords.size(); i++) {
        for (String t : targetWords) {
            for (int i2 = 0; i2 < (searchWords.get(i).length() < t
                .length() ? searchWords.get(i).length() : t
                .length()); i2++) {
            if (t.charAt(i2) == searchWords.get(i).charAt(i2))
                lm++;
            }
            if (blm[i] < lm)
            blm[i] = lm;
            lm = 0;
        }
        }

        for (int i = 0; i < blm.length; i++) {
        if (blm[i] == searchWords.get(i).length())
            mwords++;
        mletters += blm[i];
        }

        result = MessageFormat
            .format("-----\nSearch text:\"{0}\"\nWords:{1}\nLetters:{2}\n-----\nTarget text:\"{3}\"\nWords:{4}\nLetters:{5}\n-----\nMatch Results\nWords:{6}/{1}\nLetters:{7}/{2}",
                search, swords, sletters, target, twords, tletters,
                mwords, mletters);
        return result;
    }

答案 1 :(得分:1)

这似乎是一个标准的搜索引擎问题。如果查询和搜索字符串很小,则需要对查询和搜索字符串进行标记。然后在搜索字符串中按递增顺序搜索标记。

搜索引擎也这样做,并且标记化是一个非常难的问题。并非所有语言都使用空格作为分隔符。中文/日文将成为令牌化者的噩梦。