我需要实现一个过程,其中上传大约50 / 150kb的文本文件,并与大量短语(~10k)进行匹配。
我需要知道哪些词组具体匹配。
短语可能是“等等等等”或者只是“等等” - 这意味着我需要考虑字边界,因为我不希望包含中缀匹配。
我的第一次尝试是创建一个大型的预编译正则表达式列表,看起来像@"\b{0}\b"
(因为10k这些短语是不变的 - 我可以缓存并重复使用同一个列表来对付多个文档) ;
在我全新的&非常快的PC - 这种匹配需要10秒+,我希望能够减少很多。
关于我如何能够实现这一目标的任何建议都将不胜感激!
干杯, 戴夫
答案 0 :(得分:1)
您可以使用Lucene.Net
这将创建一个文本的inedx,以便您可以快速查询它。这是一个“全文索引”。
本文解释了它的全部内容:
这个库最初是用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);
我认为你会发现这种方法比正则表达式匹配要快得多,并且尊重单词边界。