regex 匹配大量字符串/短语

t2a7ltrp  于 2023-03-20  发布在  其他
关注(0)|答案(2)|浏览(143)

我需要实现一个过程,其中上载大约50/150 kb的文本文件,并与大量短语(~ 10 k)进行匹配。
我需要知道哪些短语特别匹配。
一个短语可以是“blah blah blah”或者仅仅是“blah”--意思是我需要考虑单词边界,因为我不希望包含中缀匹配。
我的第一个尝试是创建一个大型的预编译正则表达式列表,看起来像@"\b{0}\b"(因为10 k的短语是常量-我可以缓存和重用这个相同的列表对多个文档);
在我的全新的和非常快的PC -这个匹配是需要10秒+,我希望能够减少很多。
任何关于我如何能够实现这一目标的建议将不胜感激!
干杯戴夫

tv6aics1

tv6aics11#

你可以使用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);

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

wyyhbhjk

wyyhbhjk2#

您可以使用Lucene.net
这将创建一个文本索引,这样你就可以快速地查询它,这是一个“全文索引”。
这篇文章解释了它的全部内容:
Lucene.net
这个库最初是用java(Lucene)编写的,但是有一个到.NET的端口(lucene.net)。
在选择词干分析器的时候,你必须特别小心。词干分析器取一个单词的“根”,这样几个相似的单词就可以匹配(例如book和books会匹配)。如果你需要精确匹配,那么你应该使用(或实现)一个词干分析器,它会返回原始单词而不做任何改变。
创建索引和搜索结果必须使用相同的词干分析器。
您还必须查看一下语法,因为它太强大了,允许部分匹配、精确匹配等等。
你也可以看看this blog

相关问题