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

C#使用ContainsAny过滤字符串时如何实现精确匹配排除近似值

问题根因

  1. 现有ContainsAny扩展方法仅做子串包含校验,只要EMPNO字段出现M1子串就返回true,因此所有包含M1的记录都会被命中,无法过滤掉同时存在M2、M3等其他M开头编号的记录,不符合你的过滤规则。
  2. 遍历Qry1为EmpTagNo赋值时,采用的是顺序覆盖逻辑,最后一条匹配记录的EMPTAG值为40,覆盖了之前的15、20,导致最终输出结果不符合预期。

修复方案

你的EMPNO字段用+作为片段分隔符,调整匹配逻辑为:拆分EMPNO为独立片段后,校验所有格式为M+数字的片段只能有M1一个值,同时满足包含MAP的要求即可。

代码调整示例

方式1:直接修改查询逻辑(无需改扩展方法)

private void button7_Click(object sender, EventArgs e)
{
    List<string> valcontains = new List<string>() { "MAP" };
    List<string> Empcontains = new List<string>() { "M1" };
    int EmpTagNo = 0;

    DataTable tblData = new DataTable();
    tblData.Columns.Add("EMPNO", typeof(string));
    tblData.Columns.Add("EMPTAG", typeof(int));
    tblData.Columns.Add("EMPDEP", typeof(string));
    tblData.Rows.Add("(MAP) KL+M1+XZ+X1+HM", "15", "CIV");
    tblData.Rows.Add("(MAP) KL+M1+M3+X1+HM", "20", "MEC");
    tblData.Rows.Add("(MAP) KL+M1+M5+X1+HM+M7", "40", "IT");
    tblData.Rows.Add("(MAP) KL+M1+M5+X1+HM+M7", "40", "IT");
    tblData.Rows.Add("(MAP) KL+M1+M5+X1+HM+M7", "40", "IT");
    tblData.Rows.Add("(MAP) KL+M1+M5+X1+HM+M7", "40", "IT");
    tblData.Rows.Add("(MAP) KL+M1+M5+X1+HM+M7", "40", "CIV");

    // 过滤符合要求的记录
    var matchedRecords = tblData.AsEnumerable()
        .Where(r => 
            // 校验包含MAP
            valcontains.Any(r.Field<string>("EMPNO").Contains)
            &&
            // 拆分EMPNO片段,校验M开头数字格式的片段只有M1
            r.Field<string>("EMPNO").Split('+')
                .Where(seg => System.Text.RegularExpressions.Regex.IsMatch(seg, @"^M\d+$"))
                .All(seg => Empcontains.Contains(seg))
        ).ToList();

    if (matchedRecords.Any())
    {
        // 直接取第一条匹配记录的EMPTAG,避免覆盖
        EmpTagNo = matchedRecords.First().Field<int>("EMPTAG");
    }
}

方式2:新增扩展方法适配通用场景

如果需要复用该匹配逻辑,可以在ContainsStringExtensions类中新增方法:

public static class ContainsStringExtensions
{
    public static bool ContainsAny(this string haystack, IEnumerable<string> filterList)
    {
        return haystack != null && filterList.Any(haystack.Contains);
    }

    // 新增精确匹配分隔片段的方法
    public static bool MatchExactMSegment(this string haystack, IEnumerable<string> allowedMSegs, char separator = '+')
    {
        if (string.IsNullOrEmpty(haystack) || allowedMSegs == null || !allowedMSegs.Any())
            return false;

        var segments = haystack.Split(separator);
        // 筛选所有M开头+数字的片段
        var mSegments = segments.Where(seg => System.Text.RegularExpressions.Regex.IsMatch(seg, @"^M\d+$"));
        // 要求所有M类片段都在允许列表内
        return mSegments.All(seg => allowedMSegs.Contains(seg));
    }
}

调用时直接替换where条件即可:

var matchedRecords = tblData.AsEnumerable()
    .Where(r => 
        r.Field<string>("EMPNO").ContainsAny(valcontains)
        && r.Field<string>("EMPNO").MatchExactMSegment(Empcontains)
    ).ToList();

修改后只会命中第一条符合要求的记录,EmpTagNo最终值为预期的15。

内容的提问来源于stack exchange,提问作者Gani_tpt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 20:06:04