2010-08-16 2 views

ответ

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

также может делать '{$ _ -in" y "," yes "}', но я не уверен, с какой версии PS. – tkokasih

+2

@wannabeprogrammer [Оператор ** ** ** был введен в Windows PowerShell 3.0.] (Https://technet.microsoft.com/en-us/library/hh847759.aspx) –

+3

-eq нечувствителен к регистру при выполнении сравнения строк так что ToLower не нужен –

33

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

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 Переключить документация: http://technet.microsoft.com/en-us/library/ff730937.aspx

+1

Это отличное решение, хотя «технически», поскольку я просил использовать отдельные значения, я отметил fletcher как ответ. – Micah

+2

Достаточно справедливо, хотя другое регулярное выражение, вероятно, могло бы сделать то же самое. – derekerdmann

+2

Подход Regex был бы более кратким. – mseery

4

Поддержка ввода у | вы | да и нечувствительны к регистру.

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

Собственно, ваше выражение «[yes]» соответствует любому вхождению символов «y», «e» или «s» в любом месте в $ someString. Даже если $ someString «no! No! No! S», этот блок возврата вернет «Вы ввели« Да ». из-за конечных 's'. Чтобы соответствовать y | ye | yes, выражение должно быть «^ y (es?)? $". – BACON

36

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

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

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

-2

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

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

{'y' -or 'yes'} всегда оценивает значение true, поэтому ветвь по умолчанию никогда не попадает –

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

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


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

+0

Это не симпатично, это задокументировано. Добавьте оператор break, если вы не хотите, чтобы последующие ветви оценивались. – Frank

+1

@Frank Достаточно честно, «мило», возможно, не было лучшим словом для обращения к изменению поведения ключевого слова, которое было изменено или нетипично по отношению к его исторической семантике на многих языках с «C» (1975) или ранее. –

1

Небольшая модификация сообщения 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." } 
} 
Смежные вопросы