匹配大量的字符串/短语

时间:2012-09-13 09:42:17

标签: c# regex string

我需要实现一个过程,其中上传大约50 / 150kb的文本文件,并与大量短语(~10k)进行匹配。

我需要知道哪些词组具体匹配。

短语可能是“等等等等”或者只是“等等” - 这意味着我需要考虑字边界,因为我不希望包含中缀匹配。

我的第一次尝试是创建一个大型的预编译正则表达式列表,看起来像@"\b{0}\b"(因为10k这些短语是不变的 - 我可以缓存并重复使用同一个列表来对付多个文档) ;

在我全新的&非常快的PC - 这种匹配需要10秒+,我希望能够减少很多。

关于我如何能够实现这一目标的任何建议都将不胜感激!

干杯, 戴夫

2 个答案:

答案 0 :(得分:1)

您可以使用Lucene.Net

这将创建一个文本的inedx,以便您可以快速查询它。这是一个“全文索引”。

本文解释了它的全部内容:

Lucene.net

这个库最初是用java编写的(Lucene),但是有一个.NET(lucene.net)的端口。

选择割除器时必须特别小心。词干取词取词的“根”,因此几个相似的词可以匹配(即书和书将匹配)。如果你需要完全匹配,那么你应该采用(或实现)一个词干分析器,它不返回原始单词。

必须使用相同的词干分析器来创建索引和搜索结果。

您还必须查看语法,因为它功能太强,允许部分匹配,完全匹配等。

您还可以查看this blog

答案 1 :(得分:1)

你可以使用Lucene.NET和Shingle Filter,只要你不介意对短语所拥有的可能单词数量设置上限。

public class MyAnalyzer : Analyzer
{
    public override TokenStream TokenStream(string fieldName, TextReader reader)
    {       
        return new ShingleFilter(new LowerCaseFilter(new StandardTokenizer(Lucene.Net.Util.Version.LUCENE_29, reader)), 6);
    }
}

您可以使用此实用程序方法运行分析器。

public static IEnumerable<string> GetTerms(Analyzer analyzer, string keywords)
{
    var tokenStream = analyzer.TokenStream("content", new StringReader(keywords));
    var termAttribute = tokenStream.AddAttribute<ITermAttribute>();

    var terms = new HashSet<string>();

    while (tokenStream.IncrementToken())
    {
        var term = termAttribute.Term;
        if (!terms.Contains(term))
        {
            terms.Add(term);
        }
    }

    return terms;
}

检索完所有条款后,请与您的单词列表相交。

var matchingShingles = GetTerms(new MyAnalyzer(), "Here's my stuff I want to match");

var matchingPhrases = phrasesToMatch.Intersect(matchingShingles, StringComparer.OrdinalIgnoreCase);

我认为你会发现这种方法比正则表达式匹配要快得多,并且尊重单词边界。