我可以在 C# 中使用带有 switch case 的正则表达式吗?

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

我可以像这样用c#编写switch case吗?

switch (string)

case [a..z]+

//   do something

case [A..Z]+

//   do something

....
c# regex
6个回答
51
投票

是的,在 C# 7 中可以(并且没有人注意到我在字符类

..
而不是
-
中使用了不正确的范围字符)。现在更新了一个稍微更有用且实际有效的示例:

using System.Text.RegularExpressions;
string[] strings = {"ABCDEFGabcdefg", "abcdefg", "ABCDEFG"};
Array.ForEach(strings, s => {
    switch (s)
    {
        case var someVal when new Regex(@"^[a-z]+$").IsMatch(someVal):
            Console.WriteLine($"{someVal}: all lower");
            break;
        case var someVal when new Regex(@"^[A-Z]+$").IsMatch(someVal):
            Console.WriteLine($"{someVal}: all upper");
            break;
        default:
            Console.WriteLine($"{s}: not all upper or lower");
            break;
    }
});

输出:

ABCDEFGabcdefg: not all upper or lower
abcdefg: all lower
ABCDEFG: all upper

12
投票

使用 _ 作为丢弃对 David 的出色答案进行了小小的改进。 只是一个非常简单的字符串值作为示例。

using System;
using System.Text.RegularExpressions;

public class Program
{
    public static void Main()
    {
        string userName = "Fred";
        int something = 0;

        switch (true)
        {                
            case bool _ when Regex.IsMatch(userName, @"Joe"):
                something = 1;
                break;

            case bool _ when Regex.IsMatch(userName, @"Fred"):
                something = 2;
                break;

            default:            
                break;
        }    
        Console.WriteLine(something.ToString());
    }
}

10
投票

从 C# 8.0 开始,答案现在是肯定的!...有点。

在 8.0 中,引入了 switch 表达式。您可以使用它来匹配许多不同风格的图案,如下所示。

string myValueBeingTested = "asdf";
        
string theResultValue = myValueBeingTested switch
{
    var x when 
        Regex.IsMatch(x, "[a..z]+") => "everything is lowercase",
    var y when
        Regex.IsMatch(y, "[A..Z]+") => "EVERYTHING IS UPPERCASE",
    "Something Specific"            => "The Specific One",
    _                               => "The default, no match scenario"
};

它是如何工作的:switch 表达式需要一个可以将结果输入到其中的变量。上面的示例使用

theResultValue
变量来实现这一点。接下来,您将上面的 myValueBeingTested 表示的称为 范围表达式 传递到
switch
中。熟悉的 case 构造被替换为 pattern expression,后跟
=>
标记,并一起称为 expressionn armarm 标记右侧的任何内容都将最终出现在结果变量中。

通常,switch 表达式 要求模式是编译时常量,并且您不能在 switch 表达式 内执行任意代码。但是,我们可以通过使用 when 子句来使用

case gaurd
模式来利用 Regex,如上所示。每个案例都需要连接在不同的arm中,并具有不同的一次性变量(上面的
x
y
)。

上面显示的第三个arm是一个编译时常量字符串,用于根据需要匹配某些特定文本。上面显示的第四个 arm 使用

_
模式,这是一种类似于旧的
default:
关键字的通配符。您还可以使用
null
代替或补充
_
来单独处理 null 情况。

在我的 .NET Fiddle 示例中尝试一下


4
投票

你应该能够做这样的事情:

using System.Text.RegularExpressions;

private void fauxSwitch(string caseSwitch)
{
    if(Regex.Match(caseSwitch, @"[a..z]+").Success)
    {
        //do something
        return;
    }

    if(Regex.Match(caseSwitch, @"[A..Z]+").Success)
    {
        //do something
        return;
    }

    /*default*/
    //do something
}

尽管如此,C#7 中的模式匹配可能是更好的选择。


2
投票

不。在 C#(7 之前)中,switch 语句仅接受常量值。

按照您的建议使用更复杂的表达式是函数式编程世界中称为“模式匹配”的功能。

模式匹配包含在 C#7 中


0
投票

从 C# 11 开始,这变得更容易:

// named capture groups improve readability
var pattern = new Regex(@"(?<LowerCase>[a-z]+)|(?<UpperCase>[A-Z]+)");
switch(stringValue)
{
    case { Success: true, Groups: [_, { Name: "LowerCase", Success: true }, _] }:
        // do something
        break;
    case { Success: true, Groups: [_, _, { Name: "UpperCase", Success: true }] }:
        // do something
        break;
    default:
        // do something
        break;
}
© www.soinside.com 2019 - 2024. All rights reserved.