简体   繁体   English

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

[英]Can I use regex expression in c# with switch case?

Can I write switch case in c# like this?我可以像这样在 c# 中编写 switch case 吗?

switch (string)

case [a..z]+

//   do something

case [A..Z]+

//   do something

....

Yes you can in C# 7 (and nobody noticed I had used the incorrect range character in the character class .. instead of - ).是的,您可以在 C# 7 中使用(没有人注意到我在字符类中使用了不正确的范围字符..而不是- )。 Updated now with a slightly more useful example that actually works:现在更新了一个更有用的实际工作示例:

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;
    }
});

Output:输出:

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

A minor refinement on David's excellent answer using _ as a discard.使用 _ 作为丢弃对大卫的优秀答案进行了小幅改进。 Just a very simple string value as an example.只是一个非常简单的字符串值作为例子。

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());
    }
}

You should be able to do something like this:你应该能够做这样的事情:

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
}

Although, Pattern matching in C#7 is probably the better option.虽然,C#7 中的模式匹配可能是更好的选择。

No. In C# (prior to 7) the switch statement only accepts constant values.不可以。在 C#(7 之前)中,switch 语句只接受常量值。

Using more complex expressions as you've suggested is a feature known as 'pattern matching' in the functional programming world.按照您的建议使用更复杂的表达式是函数式编程世界中称为“模式匹配”的功能。

Pattern matching is included in C#7模式匹配包含在 C#7 中

Starting with C# 8.0, the answer is now YES!... sort of.从 C# 8.0 开始,现在的答案是肯定的!......有点。

With 8.0, the switch expression was introduced.在 8.0 中,引入了switch 表达式 You can use that to match many different styles of patterns as show below.您可以使用它来匹配许多不同样式的图案,如下所示。

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"
};

How it works: The switch expression needs a variable that it can feed the results into.工作原理: switch 表达式需要一个变量,它可以将结果输入到其中。 The above sample uses theResultValue variable for that.上面的示例theResultValue使用了theResultValue变量。 Next you pass into the switch what is referred to as the range expression represented by myValueBeingTested above.接下来,您将被称为由上面的myValueBeingTested表示的范围表达式传递到开关中 The familiar case construct is replaced with a pattern expression followed by the => token and together referred to as an expressionn arm .熟悉的case构造被替换为模式表达式,后跟=>标记,并一起称为expressionn arm Anything on the right side of the arm token will end up in the result variable. arm 标记右侧的任何内容都将在结果变量中结束。

Normally the switch expression requires that patterns be a compile-time constant, and you cannot execute arbitrary code inside a switch expression .通常switch 表达式要求模式是一个编译时常量,并且你不能在switch 表达式中执行任意代码。 However we can use a case gaurd pattern by using the when clause to make use of Regex as shown above.但是,我们可以通过使用when子句来使用case gaurd模式来使用Regex,如上所示。 Each case needs to be wired up in a distinct arm with distinct throw-away variables, ( x and y above).每个案例都需要连接到具有不同一次性变量的不同臂中,(上面的xy )。

The 3rd arm shown above is a compile-time constant string to match some specific text if desired.上面显示的第三个是一个编译时常量字符串,如果需要,它可以匹配一些特定的文本。 The 4th arm shown above uses the _ pattern, which is a sort of wildcard similar to the old default: keyword.上面显示的第 4 条使用_模式,这是一种类似于旧的default:关键字的通配符。 You can also use null instead of, or in addition to _ to handle null cases separately from anything else.您还可以使用null代替_或除了_之外,将 null 情况与其他任何事情分开处理。

Try it out in my .NET Fiddle sample here .在我的.NET Fiddle 示例中尝试一下

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM