JavaScript에서 문자열 일치를위한 스위치 문


193

다음 조건부에 대해 swtich를 작성하려면 어떻게합니까?

URL 에 "foo" 가 포함 된 경우 settings.base_url은 "bar"입니다.

다음은 필요한 효과를 달성하지만 스위치에서 더 관리하기 쉽다고 생각합니다.

var doc_location = document.location.href;
var url_strip = new RegExp("http:\/\/.*\/");
var base_url = url_strip.exec(doc_location)
var base_url_string = base_url[0];

//BASE URL CASES

// LOCAL
if (base_url_string.indexOf('xxx.local') > -1) {
    settings = {
        "base_url" : "http://xxx.local/"
    };
}

// DEV
if (base_url_string.indexOf('xxx.dev.yyy.com') > -1) {
    settings = {
        "base_url" : "http://xxx.dev.yyy.com/xxx/"
    };
}

답변:


352

전체 문자열 일치를 switch수행하지 않으면이를 수행 할 수 없습니다 . 하위 문자열 일치를 수행하고 있습니다. (이 아닌 아주 숀 코멘트에서 지적 하듯, 사실. 마지막에 참고를 참조하십시오.)

상단의 정규 표현식이 경기에서 비교하지 않으려는 모든 것을 제거하는 것이 행복하다면 하위 문자열 일치가 필요하지 않으며 다음을 수행 할 수 있습니다.

switch (base_url_string) {
    case "xxx.local":
        // Blah
        break;
    case "xxx.dev.yyy.com":
        // Blah
        break;
}

...하지만 다시 일치하는 완전한 문자열 인 경우에만 작동합니다 . base_url_string예를 들어 "yyy.xxx.local"인 경우 실패 하지만 현재 코드는 "xxx.local"분기의 코드와 일치합니다.


업데이트 : 좋아, 기술적 으로 하위 문자열 일치에 사용할 수switch 있지만 대부분의 상황에서는 권장하지 않습니다. 방법은 다음과 같습니다 ( 실례 ).

function test(str) {
    switch (true) {
      case /xyz/.test(str):
        display("• Matched 'xyz' test");
        break;
      case /test/.test(str):
        display("• Matched 'test' test");
        break;
      case /ing/.test(str):
        display("• Matched 'ing' test");
        break;
      default:
        display("• Didn't match any test");
        break;
    }
}

JavaScript switch문장이 작동 하는 방식 , 특히 두 가지 주요 측면 때문에 작동합니다 . 첫째, 사례는 소스 텍스트 순서 로 고려되고 , 둘째는 선택기 표현식 (키워드 뒤의 비트 case)이 해당 사례로 평가되는 표현식 입니다. 평가 (다른 언어에서와 같이 상수가 아님). 따라서 우리의 테스트 표현식은 true이므로 첫 번째 case표현식 true은 사용되는 표현식입니다 .


91
나는 그것이 오래되었다는 것을 알고 있지만 이것은 사실이 아닙니다. 실제로 할 수 있습니다switch(true) { case /foo/.test(bar): ....
— Sean Kinsey

23
맙소사! 스위치 문은 그렇게 작동하지 않아야합니다. 이것은 단순히 망가 졌으므로 그러한 일을하는 것은 불법이어야합니다.
— Pijusn

47
후후, 너무 맛있어요.
— Aditya MP

41
당신은 모두 당신의 관점을 넓히기 만하면됩니다. 루비의 표준은 추악한 점을 제외하고는 true모두 그대로 두는 것입니다.
— emkman

49
나는 이것을 좋아하고 그것을 인정하는 것을 부끄러워하지 않습니다.
— chrisf

65

RegExp는 입력 문자열에서 기술적으로뿐만 아니라 실제적으로도 사용할 수 있습니다 match.

의 출력은 match()배열 이므로 결과의 첫 번째 배열 요소를 검색해야합니다. 일치가 실패하면 함수가를 반환합니다 null. 예외 오류를 피하기 위해 ||첫 번째 배열 요소에 액세스하기 전에 조건부 연산자를 추가 하고 입력 문자열이 포함 된 정규 표현식의 정적 특성 인input 특성 에 대해 테스트 합니다.

str = 'XYZ test';
switch (str) {
  case (str.match(/^xyz/) || {}).input:
    console.log("Matched a string that starts with 'xyz'");
    break;
  case (str.match(/test/) || {}).input:
    console.log("Matched the 'test' substring");        
    break;
  default:
    console.log("Didn't match");
    break;
}

또 다른 방법은 String()생성자 를 사용하여 요소가 하나만 있어야하는 결과 배열을 캡처하는 것입니다 (캡처 그룹 없음). 전체 문자열은 한정자 ( .*)를 사용하여 문자열 로 캡처해야 합니다. 장애가 발생하면 null객체가 "null"문자열이됩니다. 편리하지 않은.

str = 'haystack';
switch (str) {
  case String(str.match(/^hay.*/)):
    console.log("Matched a string that starts with 'hay'");
    break;
}

어쨌든, 더 우아한 해결책은 단순히 부울 값을 반환하고 대소 문자를 구분하지 않고 쉽게 검색 할 수있는 /^find-this-in/.test(str)with switch (true)메소드 를 사용하는 것 입니다 .


1
pribilinsiky : test ()를 사용하는 세 번째 솔루션은 switch (true)가 필요하다는 것을 언급해야합니다.
— traday

35

location.host 속성을 사용하십시오.

switch (location.host) {
    case "xxx.local":
        settings = ...
        break;
    case "xxx.dev.yyy.com":
        settings = ...
        break;
}

1
고마워요, +1 이것이 제가 정말로해야 할 일이므로
— Dr. Frankenstein Dr.

switch 문에 전달한 변수 유형에주의해야합니다. 그것은 해야한다 문자열합니다. 당신이 할 수 있는지 확인하십시오 switch ("" + location.host).
— ceving

16

또 다른 옵션은 정규 표현식 일치 결과의input 필드 를 사용 하는 것입니다 .

str = 'XYZ test';
switch (str) {
  case (str.match(/^xyz/) || {}).input:
    console.log("Matched a string that starts with 'xyz'");
    break;
  case (str.match(/test/) || {}).input:
    console.log("Matched the 'test' substring");        
    break;
  default:
    console.log("Didn't match");
    break;
}

좋은 것. 이 경우 모든 배열 속성을 테스트에 사용할 수도 있습니다..length:
— Steven Pribilinskiy

6
var token = 'spo';

switch(token){
    case ( (token.match(/spo/) )? token : undefined ) :
       console.log('MATCHED')    
    break;;
    default:
       console.log('NO MATCH')
    break;;
}


-> 일치하는 경우 삼항식은 원래 토큰을 반환합니다.
----> 원래 토큰은 대소 문자로 평가됩니다.

-> 일치하지 않으면 삼항은 정의되지 않은 반환
----> 케이스 는 정의되지 않은 토큰과 비교하여 토큰을 평가합니다.

삼항 테스트는 예를 들어 어떤 경우에도 가능합니다.

( !!~ base_url_string.indexOf('xxx.dev.yyy.com') )? xxx.dev.yyy.com : undefined 

============================================

(token.match(/spo/) )? token : undefined ) 

A는 삼항 표현.

이 경우 테스트는 token.match (/ spo /)로, 정규 표현식 / spo / (이 경우 리터럴 문자열 spo)에 대해 token에 보유 된 문자열이 일치 하는지를 나타냅니다.

식과 문자열이 일치하면 true가되고 토큰 (스위치 문이 작동하는 문자열)이 반환됩니다.

분명히 token === token이므로 switch 문이 일치하고 사례가 평가됩니다.

스위치 문을 테스트 결과 만 볼 수 있도록 계층 구조를 살펴보면 Turnery 테스트가 스위치 문을 "전에"평가된다는 것을 이해하는 것이 더 쉽습니다.


당신의 대답은 혼란 스럽습니다. 예와 설명을 검토하고 개선 할 수 있습니까?
— falsarella

@falsarella 나는 당신이 이해하는 데 어려움이 있다고 상상 한 부분을 설명했습니다. 나는 더 간단한 예를 만들 수 있다고 생각하지 않습니다. 더 궁금한 점이 있거나 어려움에 대해 더 구체적으로 설명해 주시면 더 도와 드리겠습니다.
— James

좋아, 이제 알았다. 나는 그것이 token.match(/spo/)일치 할 것이 분명하기 때문에 혼란 스러웠다 .
— falsarella

3

더 쉬울 수 있습니다. 다음과 같이 생각하십시오.

  • 먼저 일반 문자 사이에서 문자열을 잡습니다.
  • 그 후 "케이스"를 찾으십시오

:

// 'www.dev.yyy.com'
// 'xxx.foo.pl'

var url = "xxx.foo.pl";

switch (url.match(/\..*.\./)[0]){
   case ".dev.yyy." :
          console.log("xxx.dev.yyy.com");break;

   case ".some.":
          console.log("xxx.foo.pl");break;
} //end switch

공감. 그러나 참고 :TypeError: url.match(...) is null
— 1111161171159459134

1

너무 늦었을 수도 있지만, 할당 할 때 이것을 좋아했습니다 :)

function extractParameters(args) {
    function getCase(arg, key) {
        return arg.match(new RegExp(`${key}=(.*)`)) || {};
    }

    args.forEach((arg) => {
        console.log("arg: " + arg);
        let match;
        switch (arg) {
            case (match = getCase(arg, "--user")).input:
            case (match = getCase(arg, "-u")).input:
                userName = match[1];
                break;

            case (match = getCase(arg, "--password")).input:
            case (match = getCase(arg, "-p")).input:
                password = match[1];
                break;

            case (match = getCase(arg, "--branch")).input:
            case (match = getCase(arg, "-b")).input:
                branch = match[1];
                break;
        }
    });
};

이벤트를 더 진행하여 옵션 목록을 전달하고 |


1
또한 타입 안전 || {}을 위해 || [-1]또는 이와 유사한 것으로 변경 합니다 . 또한 new RegExp슬래시뿐만 아니라 왜 사용됩니까?
— Sergey Krasilnikov

시간이 걸리지 않았습니다. 작동하는 순간 방금 계속 ..... 지금 부끄러워합니다.
— TacB0sS

당황하지 마십시오. 그것은 단지 내 젖꼭지 따기였습니다.) 사실 나는 옳지조차 모르겠지만, 새로운 것을 배우려고 노력했습니다.
— Sergey Krasilnikov

아니 ... 당신은 ... 나는 확실히 올바른 가질 수있다 generify 및 싸게 치장 내가 다시 그 코드에 도착하면 .. 내가 .. :) 곧 나는 희망이 될 것이다 것
— TacB0sS
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.