【问题标题】:How can I find the occurrence of compound words in a text如何在文本中找到复合词的出现
【发布时间】:2013-04-08 09:33:01
【问题描述】:

我正在尝试查找文本中特定单词或复合词的出现。

例如,文本是“祝你生日快乐” 我必须匹配的短语是“生日快乐”。

我有一个需要与输入文本匹配的单词/短语字典。这本词典由大约3000个单词/复合词组成。需要分析的文本数量可能会有所不同。现在我正在使用正则表达式 .\b+phrase+\b.。这给了我正确的答案,但速度很慢。

此外,在文本中找到的单词可能前面或后面有特殊字符,如!,:,。等等

虽然 text.contains() 很快,但我不能使用它,因为即使对于单词的子集它也会返回 true。有什么方法可以让我更快地做到这一点?

【问题讨论】:

  • 为什么不能使用text.contains()?单词的子集是什么意思?
  • 你在哪里存储字典?
  • 就像说,我想找的词是作者,那么即使权威错误,包含也会返回真。
  • @Sudhanshu :我正在为字典使用 ArrayList。
  • 不能将这两种方法结合起来吗?所以首先使用text.contains,只有当它返回true时,才使用较慢的正则表达式。

标签: java string


【解决方案1】:

您可以将字符串拆分为单词数组并使用Knuth-Morris-Pratt algorithm,但不是比较字符串中的字符,而是比较数组中的单词。

例如字符串:

i bought a hat in manhattan

将其拆分为数组:

S = {"i","bought","a","hat","in","manhattan"}

如果您要查找单个单词,只需将您要查找的单词与该数组中的每个单词进行比较即可。

如果你正在寻找一个单词序列,例如:

W = {"a","hat","in"}

使用 KMP。明确地,参考维基百科定义的算法,如上所述设置 S 和 W,当算法状态为 if W[i] = S[m + i] 时,您在 java 中通过以下方式实现:

if(W[i].equals(S[m+i]))

【讨论】:

  • 嘿,我也在尝试使用 KMP 和 Boyer-Moore。但是,即使单词存在并附加了其他字母,这两种算法都会返回 true。例如。说,我想找到帽子并且文本包含 man"hat"tan,然后算法返回 true。任何线索如何在不使用正则表达式的情况下处理这个问题?
  • 重点是先把字符串拆分成单词数组,我再加个例子。
【解决方案2】:

试试这个:(" " + test + " ").contains(" " + 短语 + " ");

这应该包括三个条件 -

当测试字符串以短语开头或以短语结尾时,我们的包含仍然会找到该字符串。 当短语在中间时,它会找到短语。 当短语包含空格时,我们仍然可以...

想不出其他情况……

【讨论】:

  • :谢谢。这适用于没有像 ,! 这样的特殊字符的情况。等紧随短语之后。
【解决方案3】:

我已经使用了很多java.lang.StringindexOf()substring() 方法,这可能会降低代码的性能,但下面的代码可以作为迈出的第一步接近。

public class MultiWordCompare {

    private static boolean containsWord(String word, String search) {
        if(word.indexOf(search) >= 0) { // Try if the word first exists at all
            try {
                String w = word.substring(word.indexOf(search), word.indexOf(search)+search.length()+1); //+1 to capture possible space
                if(w.lastIndexOf(" ") == w.length()-1) { //if the last char is space, then we captured the whole word
                    w = w.substring(0, w.length()-1); //remove space
                    return w.equals(search); //do string compare
                }
            }
            catch(Exception e) {
                //catching IndexOutofBoundException
            }
        }
        return false;
    }

    public static void main(String [] args) {
        System.out.println(containsWord("New York is great!", "New York"));
        System.out.println(containsWord("Many many happy Returns for the day", "happy Returns"));
        System.out.println(containsWord("New Authority", "New Author"));
        System.out.println(containsWord("New York City is great!", "N Y C"));
    }

}

这是输出

true
true
false
false

【讨论】:

  • 抱歉,我想我在问题中错过了这一点;但是 i/p 文本很可能具有像纽约这样的特殊字符!很棒,甚至我爱纽约。
  • 正如我所说,这不是一个完整的解决方案,而只是一种方法。您可以使用这段初始代码开始添加更多处理。可能我假设每个单词后面都有space ..您可以增强此代码以处理更多内容
【解决方案4】:
     String text    =
                "This is the text to be searched " +
                 "for occurrences of the http:// pattern.";

     String patternString = "This is the";

     Pattern pattern = Pattern.compile(patternString, Pattern.CASE_INSENSITIVE);
     Matcher matcher = pattern.matcher(text);

     System.out.println("lookingAt = " + matcher.lookingAt());
     System.out.println("matches   = " + matcher.matches());

来自以下网址。有关更多详细信息,请查看以下网址一次。

Matcher

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-03
    • 2012-12-14
    • 2012-07-17
    • 2021-09-30
    • 2016-02-26
    • 2018-07-24
    • 1970-01-01
    • 2016-09-18
    相关资源
    最近更新 更多