Каков синтаксис PowerShell для нескольких значений в операторе switch? - PullRequest
65 голосов
/ 16 августа 2010

Я в основном хочу сделать это:

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

Ответы [ 7 ]

77 голосов
/ 16 августа 2010
switch($someString.ToLower()) 
{ 
    {($_ -eq "y") -or ($_ -eq "yes")} { "You entered Yes." } 
    default { "You entered No." } 
}
43 голосов
/ 06 апреля 2012

Я обнаружил, что это работает и кажется более читабельным:

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

Оператор "-contains" выполняет поиск без учета регистра, поэтому вам не нужно использовать "ToLower ()".Если вы хотите, чтобы он был чувствительным к регистру, вы можете использовать вместо него «-ccontains».

42 голосов
/ 16 августа 2010

Вы должны иметь возможность использовать подстановочный знак для своих значений:

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: ИспользованиеЗаявление о переключении

6 голосов
/ 28 ноября 2016
switch($someString.ToLower())
{
    "yes"   { $_ = "y" }
    "y"     { "You entered Yes." }
    default { "You entered No." }
}

Таким образом, вы можете произвольно разветвлять, каскадировать и объединять случаи, если целевой регистр расположен ниже / после случая или случаев, когда переменная $ _ соответственно переназначается.


n.b. Каким бы симпатичным это ни было, кажется, что интерпретатор PowerShell не реализует переключение / регистр так эффективно, как можно было бы надеяться или предполагать. С одной стороны, пошаговое выполнение отладчика ISE предполагает, что вместо оптимизированного поиска, хеширования или двоичного ветвления каждый случай проверяется по очереди, как и многие операторы if-else. (Если это так, рассмотрите возможность размещения ваших наиболее распространенных случаев в первую очередь.) Кроме того, как показано в этом ответе, PowerShell продолжает тестировать случаи после их удовлетворения. И достаточно жестоко, что в .NET CIL даже есть специальный оптимизированный код операции переключения, который из-за этого поведения PowerShell не может использовать в своих интересах.

5 голосов
/ 16 августа 2010

Поддерживает ввод y | ye | yes и регистр не учитывается.

switch -regex ($someString.ToLower()) {
        "^y(es?)?$" {
            "You entered Yes." 
        }
        default { "You entered No." }
}
4 голосов
/ 16 марта 2017

Небольшая модификация поста Дерекердмана для удовлетворения первоначального запроса с использованием оператора чередования регулярных выражений "|" (pipe).

Новичкам регулярных выражений также немного легче понимать и читать.

Примечаниечто при использовании регулярных выражений, если вы не указали начало строкового символа «^» (каретка / окружность) и / или конец строкового символа «$» (доллар), то вы можете получить неожиданное / неинтуитивное поведение (например, сопоставление «вчера»)«или« почему »).

Помещение группирующих символов« () »(скобки) вокруг параметров уменьшает необходимость ставить начало и конец символов строки для каждого параметра.Без них вы получите неожиданное поведение, если не разберетесь в регулярных выражениях.Конечно, если вы обрабатываете не пользовательский ввод, а какой-то набор известных строк, он будет более читабельным без группировки и начала и конца символов строки.

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." } 
}
0 голосов
/ 03 июля 2015

После поиска решения той же проблемы, что и вы, я нашел эту небольшую тему здесь. Заранее я получил более плавное решение для этого переключателя, case case

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