如何从c#文本中搜索一个短语和它的任何单词的任何顺序



我尝试根据产品名称和描述从产品列表中进行搜索。我可以使用下面的搜索参数,其中"搜索"。表示要查找的字符串。

{(string.IsNullOrEmpty(search) || product.Name.ToLower().Contains(search)) ||
(string.IsNullOrEmpty(search) || product.Description.ToLower().Contains(search))}

这确实有效,例如,像"purus lectus malesuada"该短语是否出现在产品名称或产品描述中。现在我想买那些含有"purus"或者"purus lectus";或者"malesuada purus",即基于短语中的任何单词以任何顺序。参数应该如何修改包含方法或任何其他方法应该用于更有效的搜索?

一种方法是将搜索字符串拆分为不同的单词,并检查productname/description是否单独包含任何搜索单词。

string search = "purus lectus malesuada";
var searchWords = search.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
var productNames = new[]
{
"purus lectus",
"lorem ipsum",
"purus lectus malesuada"
};
var matches  = productNames.Where(name => searchWords.Any(name.Contains));

我希望扩展示例以适用于您的产品模型&描述不是主要问题。它还可以扩展为根据匹配的单词数量对结果排序。

另一种方法可能是检查产品名称/描述和搜索字符串之间最长的公共子字符串。要做到这一点,您可能需要设置最长公共子字符串的最小长度,或者根据长度对匹配进行排序。

关于.ToLower()的注意事项,每次调用它都会创建一个新字符串,这将导致分配。对于可能处理数百万项的搜索来说,这通常是一件坏事。一个解决办法是使用myString.IndexOf(searchString, CompareOptions.IgnoreCase) >= 0,然而,由于某种原因,这是明显比.Contains()慢,当我做了一些测量。另一种解决方法可能是运行一次.ToLower(),并在两次搜索之间存储降低后的字符串。如果这样做,您甚至可以将产品名称和描述连接起来。

最新更新