【问题标题】:What's the PowerShell syntax for multiple values in a switch statement?switch 语句中多个值的 PowerShell 语法是什么?
【发布时间】:2010-08-16 13:47:54
【问题描述】:

我基本上想这样做:

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

【问题讨论】:

    标签: powershell switch-statement


    【解决方案1】:
    switch($someString.ToLower()) 
    { 
        {($_ -eq "y") -or ($_ -eq "yes")} { "You entered Yes." } 
        default { "You entered No." } 
    }
    

    【讨论】:

    • 也可以{$_ -in "y","yes"},但我不确定是从哪个PS版本开始的。
    • -eq 在执行字符串比较时不区分大小写,因此不需要 ToLower
    • 同样,你可以这样做 { "y", "yes" -contains $_ } 这也是不区分大小写的,所以 'YES' 和 'yeS' 等等也可以。
    • switch 默认也不区分大小写。
    【解决方案2】:

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

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

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

    【讨论】:

      【解决方案3】:

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

      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 开关文档:Using the Switch Statement

      【讨论】:

      • 这是一个很好的解决方案,虽然“技术上”因为我要求使用单独的值,但我已将 fletcher 标记为答案。
      • 很公平,虽然不同的正则表达式可能会做同样的事情。
      • Regex 方法会更简洁。
      • 您实际上并不需要 ToLower(),因为在 PowerShell 中默认情况下字符串的相等性不区分大小写。
      【解决方案4】:
      switch($someString.ToLower())
      {
          "yes"   { $_ = "y" }
          "y"     { "You entered Yes." }
          default { "You entered No." }
      }
      

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


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

      【讨论】:

      • 它不可爱——它被记录在案。如果您不想评估后续分支,请添加一个 break 语句。
      • @Frank 很公平,“可爱”可能不是用来指代自“C”(1975 年)以来在众多语言中的历史语义发生改变或非典型的关键字行为的最佳词) 或更早。
      【解决方案5】:

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

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

      请注意,在使用正则表达式时,如果您没有将字符串字符 "^"(caret/circumflex) 和/或字符串结尾字符 "$"(dollar) 放在开头,那么您可能会遇到意外/不直观的行为(比如匹配“昨天”或“为什么”)。

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

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

      【讨论】:

        【解决方案6】:

        支持输入 y|ye|yes 且不区分大小写。

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

        【讨论】:

        • 实际上,您的表达式“[yes]”匹配 $someString 中任何出现的字符 'y'、'e' 或 's'。即使 $someString 是“no!no!no!s”,该开关块也会返回“您输入的是”。因为尾随的's'。要匹配 y|ye|yes,表达式应该是 "^y(es?)?$"。
        【解决方案7】:

        这是另一个。 Switch 无论如何都不区分大小写。 -eq 左边有一个数组将返回它等于的东西,返回的任何东西都是真的。

        switch($someString)
        {
          { 'y', 'yes' -eq $_ } { 'You entered Yes.' }
          default               { 'You entered No.'  }
        }
        

        【讨论】:

          【解决方案8】:

          该开关在 PowerShell 5.1 中似乎不区分大小写。下面的所有四个$someString 示例都有效。 [这是不正确的 -- js2010]

          $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
          

          【讨论】:

          • 这是一个错误的答案。正确的可能是: $a = 'b'; switch ($a) { {$_ -in 'a', 'b'} {'bingo'};默认 {'nope!'} }
          • 不错的尝试,但{"y","yes"} 对任何答案都是正确的。另一种选择:{"y","yes" -eq $_}
          【解决方案9】:

          在搜索了像你一样的问题的解决方案后,我在这里找到了这个小话题。事先我得到了这个开关的更流畅的解决方案,案例陈述

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

          【讨论】:

          • {'y' -or 'yes'} 总是评估为真,因此永远不会命中默认分支
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多