C# 使用正则表达式和 Switch 语法糖确定类型

问题描述 投票:0回答:1

我有一个基于正则表达式匹配的字符串,格式为 format_1 或 format_2 等。我使用正则表达式命名组来提取

clientId
变量。

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)) // If check, because `sampleNameFormat3` does not have this named grouping <clientId>
{
    int clientId = ParseInteger(clientIdString);
}

问题:

  1. 我进行了两次正则表达式匹配调用。有没有一种语法可以让它更干净?有什么方法可以改变 switch 语句吗?只有一次 Regex.Match 调用。
  2. 正如你在格式 3 中看到的,没有
    <clientId>
    ,所以最后一个作业
    var clientIdString = regexMatch.Result("${clientId}");
    将导致
    clientIdString = "${clientId}"

    所以,if检查会进入并出错
    ParseInteger("${clientId}")

    解决方案是这样写:
    var clientIdString = regexMatch.Groups["clientId"].Value;
    这会分配空字符串,并且 if-check 不输入。我不知道这样是否正确,所以我也想问问你的想法。
c# switch-statement syntactic-sugar
1个回答
1
投票

这种切换太过分了,并且在可读性或简洁性方面并没有真正增加太多。

就做吧

var m = Regex.Match(sampleName, sampleNameFormat1, RegexOptions.IgnoreCase);
if (!m.Success)
    m = Regex.Match(sampleName, sampleNameFormat2, RegexOptions.IgnoreCase)
if (!m.Success)
    m = Regex.Match(sampleName, sampleNameFormat3, RegexOptions.IgnoreCase)

if (m.Success)
{
    // all your other logic
}

如果您添加一些案例,那么我建议按照您和@madreflection 在评论中建议的方式循环调用。类似的东西

Match match = null;
foreach (var regexFormat in regexFormats)
{
    match = Regex.Match(sampleName, regexFormat, regexOptions.IgnoreCase);
    
    if (match.Success) break;
}

if (!match.Success) return null;

// all your other logic

Match match = null;
foreach (var regexFormat in regexFormats)
{
    match = Regex.Match(sampleName, regexFormat, regexOptions.IgnoreCase);
    
    if (match.Success)
    {
        // all your other logic
        return something...;
    }
}

return null;
© www.soinside.com 2019 - 2024. All rights reserved.