switch 문의 여러 값에 대한 PowerShell 구문은 무엇입니까?


80

기본적으로 이렇게하고 싶습니다.

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

답변:


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

30
할 수 {$_ -in "y","yes"}있지만 어떤 PS 버전 이후로 확실하지 않습니다.
tkokasih 2014


5
ToLower는이 필요하지 않도록 문자열 비교를 수행 할 때 -eq 사례를 구분하지 않습니다
보그 Gavril MSFT을

4
마찬가지로 할 수 있습니다. { "y", "yes" -contains $_ } 그리고 이것은 또한 대소 문자를 구분하지 않으므로 'YES'와 'yeS'등도 작동합니다.
TurtleZero

switch또한 대소 문자를 구분 기본적으로 있습니다.
FIL

49

나는 이것이 작동하고 더 읽기 쉽다는 것을 발견했습니다.

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

"-contains"연산자는 대소 문자를 구분하지 않는 검색을 수행하므로 "ToLower ()"를 사용할 필요가 없습니다. 대소 문자를 구분하려면 대신 "-ccontains"를 사용할 수 있습니다.


45

값에 와일드 카드를 사용할 수 있어야합니다.

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 스위치 설명서 : Switch 문 사용


1
이것은 훌륭한 솔루션이지만 "기술적으로"별도의 값을 사용하도록 요청했기 때문에 fletcher를 대답으로 표시했습니다.
Micah

2
다른 정규식이 아마도 같은 일을 할 수 있지만 충분히 공평합니다.
derekerdmann

2
정규식 접근 방식이 더 간결합니다.
mseery 2010 년

3
ToLower()PowerShell에서 기본적으로 문자열의 동일성은 대소 문자를 구분하지 않기 때문에 실제로 필요하지 않습니다 .
dan-gph 2013 년

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

대상 케이스가 $ _ 변수가 각각 재 할당 된 케이스 아래 / 뒤에 있는 한이 방식으로 케이스를 임의로 분기, 캐스케이드 및 병합 할 수 있습니다 .


nb이 동작만큼이나 귀엽지 만, PowerShell 인터프리터가 기대하거나 예상하는 것만 큼 효율적으로 스위치 / 케이스를 구현하지 않는 것으로 보입니다. 우선, ISE 디버거를 사용한 스테핑은 최적화 된 조회, 해싱 또는 이진 분기 대신 여러 if-else 문처럼 각 사례가 차례로 테스트된다는 것을 의미합니다. (그렇다면 가장 일반적인 사례를 먼저 배치하는 것이 좋습니다.) 또한이 답변에서 볼 수 있듯이 PowerShell은 사례를 충족 한 후 계속 테스트합니다. 그리고 잔인하게도 .NET CIL에서 사용할 수있는 특수 최적화 된 '스위치'opcode도 있습니다.이 동작으로 인해 PowerShell은 활용할 수 없습니다.


2
귀엽지 않습니다. 문서화되어 있습니다. 후속 분기를 평가하지 않으려면 break 문을 추가합니다.
Frank

2
@Frank Fair, "cute"는 'C'(1975) 또는 그 이전 버전 이후 여러 언어의 역사적 의미에 대해 변경되거나 비정형적인 키워드 동작을 언급하는 데 가장 적합한 단어가 아닐 수 있습니다.
Glenn Slayden

5

y | ye | yes 입력을 지원하고 대소 문자를 구분하지 않습니다.

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

13
실제로, "[yes]"표현식은 $ someString의 모든 문자 'y', 'e'또는 's'와 일치합니다. $ someString이 "no! no! no! s"인 경우에도 스위치 블록은 "You enter Yes"를 반환합니다. 후행 's'때문에. y | ye | yes와 일치하려면 표현식이 "^ y (es?)? $"여야합니다.
Lance U. Matthews

5

정규식의 대체 연산자 "|"(파이프)를 사용하여 원래 요청을 충족하도록 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." } 
}

-2

스위치는 PowerShell 5.1에서 대소 문자를 구분하지 않는 것으로 보입니다. $someString아래의 네 가지 예가 모두 작동합니다.

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

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

여기 내 $PSVersionTable데이터가 있습니다.

Name                           Value
----                           -----
PSVersion                      5.1.17763.771
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.17763.771
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

1
이것은 잘못된 대답입니다. 정답은 다음과 같습니다. $ a = 'b'; 스위치 ($ a) {{$ _ -in 'a', 'b'} { 'bingo'}; default { 'nope!'}}
Mehrdad Mirreza

-4

당신과 같은 문제에 대한 해결책을 찾은 후 여기에서이 작은 주제를 찾았습니다. 이 스위치에 대한 훨씬 더 부드러운 솔루션을 미리 얻었습니다.

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

4
{ 'y'-or 'yes'}는 항상 true로 평가되므로 기본 브랜치는 적중되지 않습니다
Darren Gosbell
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.