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.