Поделиться через


о_переключателе

Краткое описание

Описывает использование коммутатора для обработки нескольких условных инструкций.

Длинное описание

Чтобы проверить условие в скрипте или функции, можно использовать инструкцию if . Инструкция if может проверять множество типов условий, включая значение переменных и свойства объектов.

Чтобы проверить несколько условий, можно использовать инструкцию switch . Инструкция switch похожа на ряд инструкций if , но это проще. Инструкция switch перечисляет каждое условие и соответствующее действие. Если условие соответствует, выполняется действие.

Это важно

Оператор switch преобразует все значения в строки перед сравнением.

Синтаксис

Базовый switch оператор имеет следующий формат:

switch (<test-expression>) {
    <result1-to-be-matched> {<action>}
    <result2-to-be-matched> {<action>}
}

Синтаксис инструкции switch аналогичен следующим if операторам:

if ("$(<result1-to-be-matched>)") -eq ("$(<test-expression>)") {<action>}
if ("$(<result2-to-be-matched>)") -eq ("$(<test-expression>)") {<action>}

Выражения включают литеральные значения (строки или числа), переменные и блоки скриптов, возвращающие логическое значение. Оператор switch преобразует все значения в строки перед сравнением. Пример см. в разделе "Влияние преобразования строк " далее в этой статье.

Вычисляется <test-expression> в режиме выражения. Если выражение возвращает несколько значений, таких как массив или другой перечисляемый тип, switch инструкция вычисляет каждое перечисленное значение отдельно.

Выражение <result-to-be-matched> должно разрешаться в одно значение. Это значение сравнивается с входным значением.

Значение default зарезервировано для действия, используемого при отсутствии других совпадений.

Оператор switch может использовать $_ и $switch автоматические переменные. Автоматическая переменная содержит значение выражения, переданного switch инструкции, и доступно для оценки и использования в пределах области инструкций <result-to-be-matched> . Дополнительные сведения см. в статье about_Automatic_Variables.

switch Полный синтаксис инструкции выглядит следующим образом:

switch [-Regex | -Wildcard | -Exact] [-CaseSensitive] (<test-expression>) {
    string | number | variable | { <value-scriptblock> }
        { <action-scriptblock> }
    default { <action-scriptblock> } # optional
}

или

switch [-Regex | -Wildcard | -Exact] [-CaseSensitive] -File filename {
    string | number | variable | { <value-scriptblock> }
        { <action-scriptblock> }
    default { <action-scriptblock> }  # optional
}

Если параметры не используются, switch ведет себя так же, как и с помощью параметра Exact. Он выполняет нечувствительное совпадение регистра для значения. Если значение является коллекцией, каждый элемент вычисляется в том порядке, в котором он отображается.

Оператор switch должен содержать по крайней мере одну инструкцию условия.

Предложение default активируется, если значение не соответствует ни одному из условий. Это эквивалентно предложению else в инструкции if. В каждой default инструкции разрешено только одно switch предложение.

switch имеет следующие параметры:

  • Подстановочный знак — указывает, что условие является подстановочным знаком . Если предложение match не является строкой, параметр игнорируется. При сравнении учитывается регистр букв.
  • Точное — указывает, что предложение соответствия, если это строка, должно соответствовать точно. Если предложение match не является строкой, этот параметр игнорируется. При сравнении учитывается регистр букв.
  • CaseSensitive — выполняет сопоставление с учетом регистра. Если предложение match не является строкой, этот параметр игнорируется.
  • файл — принимает входные данные из файла, а не <test-expression>. Файл считывается по строке за раз и оценивается оператором switch. По умолчанию сравнение не учитывает регистр. Параметр файла поддерживает только один файл. Если включены несколько параметров файла , используется только последний. Дополнительные сведения см. в примерах параметров файла.
  • Regex — выполняет регулярное выражение, соответствующее значению условия. Если предложение match не является строкой, этот параметр игнорируется. При сравнении учитывается регистр букв. Автоматическая $Matches переменная доступна для использования в блоке инструкций сопоставления.

Примечание.

При указании конфликтующих значений, таких как Regex и Подстановочный знак, последний указанный параметр имеет приоритет, и все конфликтующие параметры игнорируются. Также разрешено несколько экземпляров параметров. Однако используется только последний указанный параметр.

Примеры

В следующих примерах показано использование инструкции switch .

Простые примеры сопоставления

В следующем примере оператор switch сравнивает значение теста 3 с каждым из условий. Когда тестовое значение соответствует условию, выполняется действие.

switch (3) {
    1 { "It's one."   }
    2 { "It's two."   }
    3 { "It's three." }
    4 { "It's four."  }
}
It's three.

В этом примере значение сравнивается с каждым условием в списке. В приведенном ниже операторе switch есть два условия для значения 3, которое показывает, что все условия тестируются.

switch (3) {
    1 { "It's one."    }
    2 { "It's two."    }
    3 { "It's three."  }
    4 { "It's four."   }
    3 { "Three again." }
}
It's three.
Three again.

Использование break и continue управление потоком

Если значение соответствует нескольким условиям, выполняется действие для каждого условия. Чтобы изменить это поведение, используйте break ключевые слова или continue ключевые слова.

Ключевое break слово останавливает обработку и завершает инструкцию switch .

Ключевое continue слово перестает обрабатывать текущее значение, но продолжает обрабатывать все последующие значения.

В следующем примере выполняется обработка массива чисел и отображение, если они нечетные или даже. Отрицательные числа пропускаются с ключевым словом continue . Если обнаружено не число, выполнение завершается с помощью ключевого break слова.

switch (1,4,-1,3,"Hello",2,1) {
    {$_ -lt 0}           { continue }
    {$_ -isnot [int32]}  { break }
    {$_ % 2}             { "$_ is Odd" }
    {-not ($_ % 2)}      { "$_ is Even" }
}
1 is Odd
4 is Even
3 is Odd

Влияние преобразования строк

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

switch ( ([datetime]'1 Jan 1970').DayOfWeek ) {
    4            { 'The integer value matches a Thursday.' }
    "4"          { 'The numeric string matches a Thursday.' }
    "Thursday"   { 'The string value matches a Thursday.' }
    { 4 -eq $_ } { 'The expression matches a Thursday.' }
}

Свойство DayOfWeek объекта date является перечислением. Хотя перечисления можно сравнить с числовыми или строковыми значениями, switch инструкция преобразует значение в строковое представление перечисления.

The string value matches a Thursday.
The expression matches a Thursday.

Это поведение отличается от поведения -eq сравнения в операторе if .

if (4 -eq ([datetime]'1 Jan 1970').DayOfWeek) {
    'The integer value matches a Thursday.'
}
The value matches a Thursday.

В этом примере хэш-файл передается инструкции switch . Хэш-файл switch преобразуется в строку.

$test = @{
    Test  = 'test'
    Test2 = 'test2'
}

$test.ToString()
System.Collections.Hashtable

Обратите внимание, что строковое представление хэш-файла не совпадает со значением ключа test .

switch -Exact ($test) {
    'System.Collections.Hashtable' { 'Hashtable string coercion' }
    'test'                         { 'Hashtable value' }
}
Hashtable string coercion

Использование switch для проверки значений в хэш-таблицы

В этом примере switch инструкция проверяет тип значения в хэш-файле. Перед проверкой значений необходимо перечислить элементы в хэш-таблицы. Чтобы избежать осложнений преобразования строк, используйте блок скрипта, возвращающий логическое значение, чтобы выбрать блок скрипта действия для выполнения.

$var = @{A = 10; B = 'abc'}

foreach ($key in $var.Keys) {
    switch ($var[$key].GetType()) {
        { $_ -eq [int32]  }  { "$key + 10 = $($var[$key] + 10)" }
        { $_ -eq [string] }  { "$key = $($var[$key])"           }
    }
}
A + 10 = 20
B = abc

Использование подстановочных знаков с switch

В этом примере нет соответствующего случая, поэтому выходные данные отсутствуют.

switch ("fourteen") {
    1     { "It's one.";   break }
    2     { "It's two.";   break }
    3     { "It's three."; break }
    4     { "It's four.";  break }
    "fo*" { "That's too many."   }
}

default Добавив предложение, можно выполнить действие, если другие условия не будут выполнены.

switch ("fourteen") {
    1       { "It's one.";   break }
    2       { "It's two.";   break }
    3       { "It's three."; break }
    4       { "It's four.";  break }
    "fo*"   { "That's too many."   }
    default { "No matches"         }
}
No matches

Чтобы слово fourteen соответствовало варианту, необходимо использовать параметр -Wildcard или -Regex.

switch -Wildcard ("fourteen") {
    1     { "It's one.";   break }
    2     { "It's two.";   break }
    3     { "It's three."; break }
    4     { "It's four.";  break }
    "fo*" { "That's too many."   }
}
That's too many.

Использование регулярных выражений с switch

В следующем примере используется -Regex параметр.

$target = 'https://bing.com'
switch -Regex ($target) {
    '^ftp\://.*$'
        {
            "$_ is an ftp address"
            break
        }
    '^\w+@\w+\.com|edu|org$'
        {
            "$_ is an email address"
            break
        }
    '^(http[s]?)\://.*$'
        {
            "$_ is a web address that uses $($Matches[1])"
            break
        }
}
https://bing.com is a web address that uses https

В следующем примере показано использование блоков скриптов в качестве switch условий инструкции.

switch ("Test") {
    { $_ -is [string] } { "Found a string" }
    "Test"              { "This $_ executes as well" }
}
Found a string
This Test executes as well

В следующем примере выполняется обработка массива, содержащего два значения даты. Свойство <value-scriptblock> Year сравнивается с каждой датой. Отображается <action-scriptblock> приветственное сообщение или количество дней до начала 2022 года.

switch ((Get-Date 1-Jan-2022), (Get-Date 25-Dec-2021)) {
    { $_.Year -eq 2021 }
        {
            $days = ((Get-Date 1/1/2022) - $_).Days
            "There are $days days until 2022."
        }
    { $_.Year -eq 2022 } { 'Welcome to 2022!' }
}

Чтение содержимого файла с помощью switch

Использование инструкции switch с параметром файла является эффективным способом обработки больших файлов по строкам. PowerShell передает строки файла в инструкцию switch. Каждая строка обрабатывается по отдельности.

Вы можете завершить обработку перед достижением конца файла с помощью ключевого слова break в инструкции действия. Оператор switch эффективнее, чем использование Get-Content для обработки больших файлов по строкам.

Вы можете объединить switch -File с -Wildcard или -Regex для гибкого и эффективного сопоставления шаблонов по строкам.

В следующем примере считывается README.md в репозитории PowerShell-Docs. Он выводит каждую строку, пока не достигнет строки, начинающейся с ##.

switch -Regex -File .\README.md {
    '^##\s' { break }
    default { $_; continue }
}

Аргумент <filename> принимает выражения подстановочных знаков, но он должен соответствовать только одному файлу. Следующий пример совпадает с предыдущим, за исключением того, что он использует подстановочный знак в аргументе <filename>. Этот пример работает, так как шаблон подстановочного знака соответствует только одному файлу.

switch -Regex -File .\README.* {
    '^##\s' { break }
    default { $_; continue }
}

Вы должны экранировать символы, которые можно интерпретировать как подстановочные знаки, если они будут рассматриваться как литералы.

$file = (New-Item -Path 'Temp:\Foo[0]' -Value Foo -Force).FullName
switch -File $file { Foo { 'Foo' } }
# No files matching '...\Temp\Foo[0]' were found.

$fileEscaped = [WildcardPattern]::Escape($file)
switch -File $fileEscaped { foo { 'Foo' } }
# Foo

См. также