在switch语句中用于多个值的PowerShell语法是什么?


78

我基本上想这样做:

switch($someString.ToLower())
{
    "y", "yes" { "You entered Yes." }
    default { "You entered No." }
}

Answers:


87
switch($someString.ToLower()) 
{ 
    {($_ -eq "y") -or ($_ -eq "yes")} { "You entered Yes." } 
    default { "You entered No." } 
}

29
也可以,{$_ -in "y","yes"}但是我不确定从哪个PS版本开始。
tkokasih 2014年


5
-eq在执行字符串比较时不区分大小写,因此不需要ToLower
Bogdan Gavril MSFT

4
同样,您可以执行{ "y", "yes" -contains $_ } 并且这也不区分大小写,因此'YES'和'yeS'等也可以使用。
TurtleZero

49

我发现这行得通,并且似乎更具可读性:

switch($someString)
{
    { @("y", "yes") -contains $_ } { "You entered Yes." }
    default { "You entered No." }
}

“ -contains”运算符执行不区分大小写的搜索,因此您无需使用“ ToLower()”。如果确实要区分大小写,则可以改用“ -ccontains”。


45

您应该能够对值使用通配符:

switch -wildcard ($someString.ToLower())
{
    "y*" { "You entered Yes." }
    default { "You entered No." }
}

也允许使用正则表达式。

switch -regex ($someString.ToLower())
{
    "y(es)?" { "You entered Yes." }
    default { "You entered No." }
}

PowerShell开关文档:使用Switch语句


1
这是一个很好的解决方案,尽管自从我要求使用单独的值以来就“技术上”,但我已将fletcher标记为答案。
米卡

2
足够公平,尽管不同的正则表达式可能会做同样的事情。
derekerdmann

2
正则表达式的方法会更简洁。
mseery 2010年

3
您实际上并不需要,ToLower()因为在PowerShell中默认情况下字符串的相等性不区分大小写。
dan-gph 2013年

7
switch($someString.ToLower())
{
    "yes"   { $_ = "y" }
    "y"     { "You entered Yes." }
    default { "You entered No." }
}

只要目标案例位于分别重新分配了$ _变量的案例的下方/之后,就可以以这种方式任意分支,级联和合并案例。


nb尽管这种行为很可爱,但似乎表明PowerShell解释器没有像人们希望或假定的那样有效地实现switch / case。首先,使用ISE调试器建议不要像优化查找,哈希或二进制分支那样,依次测试每种情况,就像许多if-else语句一样。(如果是这样,请考虑将最常见的案例放在首位。)此外,如该答案所示,PowerShell在满足案例后继续测试案例。而且非常残酷的是,.NET CIL中甚至恰好有一个经过特殊优化的“开关”操作码,由于这种行为,PowerShell无法利用它。


2
它不是可爱的-有文件记录。如果您不希望评估后续分支,请添加break语句。
弗兰克

2
@Frank足够公平,“ Cute”可能不是最合适的词,它指的是自'C'(1975)或更早版本以来在许多语言中相对于其历史语义已改变或不典型的关键字行为。
Glenn Slayden '17年

5

支持输入y | ye |是,并且不区分大小写。

switch -regex ($someString.ToLower()) {
        "^y(es?)?$" {
            "You entered Yes." 
        }
        default { "You entered No." }
}

13
实际上,您的表达式“ [yes]”与$ someString中任意位置出现的字符“ y”,“ e”或“ s”匹配。即使$ someString为“ no!no!no!s”,该切换块也将返回“您输入的是”。由于末尾有“ s”。要匹配y | ye | yes,表达式应为“ ^ y(es?)?$”。
培根

5

使用正则表达式的交替运算符“ |”(管道)对derekerdmann的帖子进行了少许修改,以满足原始请求。

正则表达式新手也更容易理解和阅读。

请注意,在使用正则表达式时,如果您不输入字符串字符“ ^”(插入符号/抑扬音符)的开始和/或字符串字符“ $”(美元)的结尾,则可能会出现意想不到的/不直观的行为(例如匹配“昨天”或“为什么”)。

在选项周围放置分组字符“()”(括号)可减少对每个选项放置字符串字符的开头和结尾的需要。没有它们,如果您不熟悉正则表达式,则可能会得到意外的行为。当然,如果您不是在处理用户输入,而是在处理一组已知的字符串,则无需分组以及字符串字符的开始和结束,它就会更具可读性。

switch -regex ($someString) #many have noted ToLower() here is redundant
{
        #processing user input
    "^(y|yes|indubitably)$" { "You entered Yes." }

        # not processing user input
    "y|yes|indubitably" { "Yes was the selected string" } 
    default { "You entered No." } 
}

-2

在PowerShell 5.1中,该开关似乎不区分大小写。以下所有四个$someString示例均有效。

$someString = "YES"
$someString = "yes"
$someString = "yEs"
$someString = "y"

switch ($someString) {
   {"y","yes"} { "You entered Yes." }
   Default { "You didn't enter Yes."}
}

这是我的$PSVersionTable数据。

Name                           Value
----                           -----
PSVersion                      5.1.17763.771
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.771
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

1
这是一个错误的答案。正确的可能是:$ a ='b'; 切换($ a){{$ _ -in'a','b'} {'bingo'}; 默认{'nope!'}}
Mehrdad Mirreza

-4

在搜索了像您一样的问题的解决方案之后,我在这里找到了这个小话题。事先,我获得了一个更流畅的解决方案,case语句

switch($someString) #switch is caseINsensitive, so you don't need to lower
{
    { 'y' -or 'yes' } { "You entered Yes." }
    default { "You entered No." }
}

4
{'y'-或'yes'}始终为true,因此永远不会点击默认分支
Darren Gosbell 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.