web-dev-qa-db-fra.com

Quelle est la syntaxe PowerShell pour plusieurs valeurs dans une instruction switch?

Je veux fondamentalement faire ceci:

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

J'ai trouvé que cela fonctionne et semble plus lisible:

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

L'opérateur "-contains" effectue une recherche non sensible à la casse, vous n'avez donc pas besoin d'utiliser "ToLower ()". Si vous voulez qu'il soit sensible à la casse, vous pouvez utiliser "-ccontains" à la place.

43
Jimmy

Vous devriez pouvoir utiliser un caractère générique pour vos valeurs:

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

Les expressions régulières sont également autorisées.

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

Documentation sur le commutateur PowerShell: tilisation de l'instruction Switch

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

Vous pouvez arbitrairement créer des branches, des cascades et des fusions de cette manière, à condition que le cas cible soit localisé en dessous/après le ou les cas où la variable $ _ est respectivement réaffectée.


nb Aussi mignon que soit ce comportement, il semble révéler que l'interpréteur PowerShell n'implémente pas le commutateur/la casse aussi efficacement que l'on pourrait l'espérer ou le supposer. D'une part, l'utilisation du débogueur ISE suggère qu'au lieu d'optimiser la recherche, le hachage ou la création de branches binaires, chaque cas est testé à son tour, à l'instar de nombreuses instructions if-else. (Si tel est le cas, envisagez d’abord les cas les plus courants.) De même, comme le montre cette réponse, PowerShell continue de tester les cas après en avoir satisfait un. Et assez cruellement, il existe même un opcode 'switch' optimisé spécial disponible dans .NET CIL dont, en raison de ce comportement, PowerShell ne peut en tirer parti.

6
Glenn Slayden

Prise en charge de la saisie y | ye | yes et insensible à la casse.

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

Une légère modification du message de derekerdmann pour répondre à la demande initiale à l'aide de l'opérateur d'alternance de regex "|" (pipe).

Il est également un peu plus facile à comprendre et à lire pour les débutants en regex.

Notez que lorsque vous utilisez regex, si vous ne mettez pas le caractère de début de chaîne "^" (caret/circumflex) et/ou le caractère de fin de chaîne "$" (dollar), vous risquez d'obtenir un comportement inattendu/non intuitif (comme la correspondance " hier "ou" pourquoi ").

Si vous mettez des caractères de regroupement "()" (parenthèses) autour des options, vous évitez de mettre des caractères de début et de fin de chaîne pour chaque option. Sans eux, vous aurez peut-être un comportement inattendu si vous n'êtes pas averti avec regex. Bien sûr, si vous ne traitez pas une entrée utilisateur, mais plutôt un ensemble de chaînes connues, celle-ci sera plus lisible sans regroupement ni caractères de début et de fin de chaîne.

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