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

C#如何在字符串中查找符合通配规则的目标子串

字符串模糊匹配效率问题

我有如下字符串(长度可能更长):

string list = "ABCDGGWWWW1234567 ABCDGGWWWW1234568 ABCDGGWWWW1234569 "; 

需要判断子串ABCDGGWWWW1234568是否存在于该字符串中,原本用如下代码即可实现:

list.IndexOf("ABCDGGWWWW1234568 ") >= 0;

现在有新需求:如果搜索的子串为ABCDXXWWWW1234568,也需要返回true。规则说明:待匹配字符串固定为17位大写字符,第5、6位要么是原值要么是XX,不会出现仅单字符替换的情况。

我之前尝试直接用下划线、问号作为通配符写了如下代码:

list.IndexOf("ABCD__WWWW1234568 ") >= 0;
list.IndexOf("ABCD??WWWW1234568 ") >= 0;

但运行后一直返回-1,无法生效。目前参考@PanagiotisKanavos的方案,通过正则实现了功能:

chassis = chassis.Substring(0, 4) + @"\S{2}" + chassis.Substring(6, 11) + @"\s+";
bool result = Regex.IsMatch(list, chassis);

请问实现该需求的最高效方式是什么?


回答

首先string.IndexOf本身不支持通配符语法,下划线、问号会被当做普通字符匹配,因此无法生效。

最高效的实现方式取决于使用场景:

1. 超高性能场景(高频调用/待匹配字符串超长)

直接做两次精确匹配即可,规则只允许第5、6位是原值或XX,不需要引入通配符:

// 输入的待匹配模板串,示例为"ABCDGGWWWW1234568"
string targetTemplate = "ABCDGGWWWW1234568";
string targetOrigin = targetTemplate;
string targetXX = targetTemplate.Substring(0,4) + "XX" + targetTemplate.Substring(6);

// 任意一个匹配成功就返回true
bool isExist = list.IndexOf(targetOrigin) >= 0 || list.IndexOf(targetXX) >= 0;

该方案性能比正则高1~2个数量级,原因:

  • 直接调用系统底层优化过的字符串匹配逻辑,无正则表达式的解析、编译开销
  • 逻辑严谨,不会出现正则通配符匹配到非预期字符的问题
  • 代码简单易维护,没有额外依赖

2. 规则可扩展场景

如果后续可能调整通配规则,可以使用预编译正则降低开销:

// 正则提前静态编译,全局只初始化一次
private static readonly Regex _chassisMatchRegex = new Regex(@"ABCD(?:GG|XX)WWWW1234568", RegexOptions.Compiled);

// 调用时直接匹配
bool result = _chassisMatchRegex.IsMatch(list);

如果模板是动态生成的,可以调整为:

string prefix = Regex.Escape(chassis.Substring(0,4));
string midOrigin = Regex.Escape(chassis.Substring(4,2));
string suffix = Regex.Escape(chassis.Substring(6));

Regex dynamicRegex = new Regex($"{prefix}(?:{midOrigin}|XX){suffix}", RegexOptions.Compiled);
bool result = dynamicRegex.IsMatch(list);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:45:02