Switch 语句中多个值的 PowerShell 语法是什么?

我基本上想这样做:

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

You should be able to use a wildcard for your values:

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

Regular expressions are also allowed.

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

PowerShell switch documentation: Using the Switch Statement

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

Supports entering y|ye|yes and case insensitive.

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

I found that this works and seems more readable:

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

The "-contains" operator performs a non-case sensitive search, so you don't need to use "ToLower()". If you do want it to be case sensitive, you can use "-ccontains" instead.

After searching a solution for the same problem like you, I've found this small topic here. In advance I got a much smoother solution for this switch, case statement

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

You can arbitrarily branch, cascade, and merge cases in this fashion, as long as the target case is located below/after the case or cases where the $_ variable is respectively reassigned.


n.b. As cute as this behavior is, it seems to reveal that the PowerShell interpreter is not implementing switch/case as efficiently as one might hope or assume. For one, stepping with the ISE debugger suggests that instead of optimized lookup, hashing, or binary branching, each case is tested in turn, like so many if-else statements. (If so, consider putting your most common cases first.) Also, as shown in this answer, PowerShell continues testing cases after having satisfied one. And cruelly enough, there even happens to be a special optimized 'switch' opcode available in .NET CIL which, because of this behavior, PowerShell can't take advantage of.

A slight modification to derekerdmann's post to meet the original request using regex's alternation operator "|"(pipe).

It's also slightly easier for regex newbies to understand and read.

Note that while using regex, if you don't put the start of string character "^"(caret/circumflex) and/or end of string character "$"(dollar) then you may get unexpected/unintuitive behavior (like matching "yesterday" or "why").

Putting grouping characters "()"(parentheses) around the options reduces the need to put start and end of string characters for each option. Without them, you'll get possibly unexpected behavior if you're not savvy with regex. Of course, if you're not processing user input, but rather some set of known strings, it will be more readable without grouping and start and end of string characters.

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

The switch doesn't appear to be case sensitive in PowerShell 5.1. All four of the $someString examples below work. [Fixed, thanks js2010]

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


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

Here's another one. Switch is case insensitive anyway. -eq with an array on the left will return the thing it's equal to, and anything returned is true.

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