You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

正则搜索如何匹配所有单词?SQL多列(含姓名组合)搜索实现

解决姓名组合搜索的问题

现有代码的核心问题是:当输入「Walter White」这类带空格的组合字符串时,会用整个字符串去匹配Name或Surname列,而这两列单独存储名和姓,自然匹配失败。要实现姓名组合搜索,需要先拆分搜索关键词,再验证这些关键词是否分布在Name和Surname中。

具体修改步骤

  1. 拆分搜索关键词:将用户输入的字符串按空格分割,过滤空字符串,得到关键词列表。
  2. 新增姓名组合匹配逻辑:如果关键词数量≥2,检查这些关键词是否分别出现在Name和Surname中(支持不区分顺序或严格顺序匹配,按需调整)。
  3. 优化去重逻辑:用HashSet存储已匹配的ID,替代原代码中效率低下的results.Any判断。

修改后的代码示例

var searchKeywords = search.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
var pattern = @$"({search})";
var matchedIds = new HashSet<int>(); // 用HashSet提升去重检查效率
var results = new List<Member>();

foreach (var member in context.Members.Where(x => x.IsActive))
{
    if (matchedIds.Contains(member.Id)) continue;

    bool isMatched = false;
    // 原有单字段匹配逻辑
    if (!string.IsNullOrEmpty(member.Name) && Regex.IsMatch(member.Name, pattern, RegexOptions.IgnoreCase))
    {
        isMatched = true;
    }
    else if (!string.IsNullOrEmpty(member.Surname) && Regex.IsMatch(member.Surname, pattern, RegexOptions.IgnoreCase))
    {
        isMatched = true;
    }
    else if (!string.IsNullOrEmpty(member.Email) && Regex.IsMatch(member.Email, pattern, RegexOptions.IgnoreCase))
    {
        isMatched = true;
    }
    else if (!string.IsNullOrEmpty(member.IdNumber) && Regex.IsMatch(member.IdNumber, pattern, RegexOptions.IgnoreCase))
    {
        isMatched = true;
    }
    // 新增姓名组合匹配逻辑(支持不区分关键词顺序)
    else if (searchKeywords.Length >= 2)
    {
        var nameParts = new[] { member.Name?.Trim(), member.Surname?.Trim() }.Where(s => !string.IsNullOrEmpty(s));
        isMatched = searchKeywords.All(keyword => 
            nameParts.Any(part => 
                Regex.IsMatch(part, $@"({keyword})", RegexOptions.IgnoreCase)));
    }

    if (isMatched)
    {
        results.Add(member);
        matchedIds.Add(member.Id);
    }
}

逻辑说明

  • 关键词拆分:处理多空格、首尾空格的情况,确保得到有效关键词。
  • HashSet去重:HashSet.Contains是O(1)操作,远快于原代码的遍历检查。
  • 姓名组合匹配:默认支持任意顺序的关键词匹配(比如「White Walter」也能找到Name=Walter、Surname=White的用户)。如果需要严格按名+姓的顺序匹配,可替换为以下逻辑:
    else if (searchKeywords.Length >= 2)
    {
        bool matchNameFirst = !string.IsNullOrEmpty(member.Name) && Regex.IsMatch(member.Name, $@"({searchKeywords[0]})", RegexOptions.IgnoreCase)
                            && !string.IsNullOrEmpty(member.Surname) && Regex.IsMatch(member.Surname, $@"({searchKeywords[1]})", RegexOptions.IgnoreCase);
        bool matchSurnameFirst = !string.IsNullOrEmpty(member.Name) && Regex.IsMatch(member.Name, $@"({searchKeywords[1]})", RegexOptions.IgnoreCase)
                               && !string.IsNullOrEmpty(member.Surname) && Regex.IsMatch(member.Surname, $@"({searchKeywords[0]})", RegexOptions.IgnoreCase);
        isMatched = matchNameFirst || matchSurnameFirst;
    }
    

额外优化建议

如果数据库数据量较大,当前内存循环匹配的方式效率较低,建议将逻辑转换为EF Core可解析的LINQ表达式,让数据库直接执行查询,避免加载所有Active成员到内存中。

内容的提问来源于stack exchange,提问作者Logany-hi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 05:16:23