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

C#中使用Switch语法糖结合正则判断格式的优化问题

正则匹配优化问题解答

先看原始代码:

var sampleName = "001-99-26Jul2023";
var sampleNameFormat1 = @"[0-9]{3}-(?<clientId>[0-9]{2})-[0-9]{2}[a-zA-Z]{3}[0-9]{4}";
var sampleNameFormat2 = @"[0-9]{4}-(?<clientId>[0-9]{2})-[0-9]{2}[a-zA-Z]{3}[0-9]{4}";
var sampleNameFormat3 = @"[0-9]{5}-[0-9]{2}[a-zA-Z]{3}[0-9]{4}";

var regexMatch = sampleName switch
{
    var _ when Regex.IsMatch(sampleName, sampleNameFormat1, RegexOptions.IgnoreCase) => Regex.Match(sampleName, sampleNameFormat1, RegexOptions.IgnoreCase),
    var _ when Regex.IsMatch(sampleName, sampleNameFormat2, RegexOptions.IgnoreCase) => Regex.Match(sampleName, sampleNameFormat2, RegexOptions.IgnoreCase),
    var _ when Regex.IsMatch(sampleName, sampleNameFormat3, RegexOptions.IgnoreCase) => Regex.Match(sampleName, sampleNameFormat3, RegexOptions.IgnoreCase),
    _ => null,
};


var clientIdString = regexMatch.Result("${clientId}");

if(!string.IsNullOrEmpty(clientIdString)) // 因sampleNameFormat3无<clientId>命名组需做判断
{
    int clientId = ParseInteger(clientIdString);
}

针对你的两个问题,解答如下:

1. 避免重复正则匹配的优化方案

原始代码每个分支先调用Regex.IsMatch再调用Regex.Match,会执行两次匹配操作,完全可以优化为只调用一次Match并复用结果,提供两种方案:

方案一:模式匹配简化switch分支

直接在switch条件分支里调用Match,通过模式匹配判断是否匹配成功,同时捕获匹配结果:

var regexMatch = sampleName switch
{
    _ when Regex.Match(sampleName, sampleNameFormat1, RegexOptions.IgnoreCase) is { Success: true } match => match,
    _ when Regex.Match(sampleName, sampleNameFormat2, RegexOptions.IgnoreCase) is { Success: true } match => match,
    _ when Regex.Match(sampleName, sampleNameFormat3, RegexOptions.IgnoreCase) is { Success: true } match => match,
    _ => null
};

方案二:正则列表循环匹配(更易扩展)

如果后续要新增格式,把正则表达式放到列表里循环匹配会更简洁,每个正则仅执行一次Match:

var regexList = new List<Regex>
{
    new Regex(sampleNameFormat1, RegexOptions.IgnoreCase),
    new Regex(sampleNameFormat2, RegexOptions.IgnoreCase),
    new Regex(sampleNameFormat3, RegexOptions.IgnoreCase)
};

var regexMatch = regexList.Select(r => r.Match(sampleName))
                          .FirstOrDefault(match => match.Success);

2. 命名组不存在时的处理方式

改用regexMatch.Groups["clientId"].Value的处理方式是正确的,还可以优化得更严谨:

  • 当正则不包含clientId命名组时,Groups["clientId"]会返回一个Group对象,其Value属性为空字符串,!string.IsNullOrEmpty判断可以正确跳过format_3的情况。
  • 额外建议:先判断regexMatch是否为null,再检查命名组是否存在,避免空引用异常:
if (regexMatch != null && regexMatch.Groups.ContainsKey("clientId") 
    && !string.IsNullOrEmpty(regexMatch.Groups["clientId"].Value))
{
    int clientId = ParseInteger(regexMatch.Groups["clientId"].Value);
}

这样既覆盖了regexMatch为null(无匹配格式)的场景,又明确确认命名组存在后再取值,逻辑更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:39:55