Switch statement for string matching in JavaScript

前端 未结 9 1488
深忆病人
深忆病人 2020-11-29 15:46

How do I write a swtich for the following conditional?

If the url contains \"foo\", then settings.base_url is \"bar\".

The following is achi

相关标签:
9条回答
  • 2020-11-29 16:35

    You can't do it in a switch unless you're doing full string matching; that's doing substring matching. (This isn't quite true, as Sean points out in the comments. See note at the end.)

    If you're happy that your regex at the top is stripping away everything that you don't want to compare in your match, you don't need a substring match, and could do:

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

    ...but again, that only works if that's the complete string you're matching. It would fail if base_url_string were, say, "yyy.xxx.local" whereas your current code would match that in the "xxx.local" branch.


    Update: Okay, so technically you can use a switch for substring matching, but I wouldn't recommend it in most situations. Here's how (live example):

    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;
        }
    }
    

    That works because of the way JavaScript switch statements work, in particular two key aspects: First, that the cases are considered in source text order, and second that the selector expressions (the bits after the keyword case) are expressions that are evaluated as that case is evaluated (not constants as in some other languages). So since our test expression is true, the first case expression that results in true will be the one that gets used.

    0 讨论(0)
  • 2020-11-29 16:35

    It may be easier. Try to think like this:

    • first catch a string between regular characters
    • after that find "case"

    :

    // '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
    
    0 讨论(0)
  • 2020-11-29 16:40

    Self-contained version that increases job security:

    switch((s.match(r)||[null])[0])
    

    function identifyCountry(hostname,only_gov=false){
        const exceptionRe = /^(?:uk|ac|eu)$/ ; //https://en.wikipedia.org/wiki/Country_code_top-level_domain#ASCII_ccTLDs_not_in_ISO_3166-1
        const h = hostname.split('.');
        const len = h.length;
        const tld = h[len-1];
        const sld = len >= 2 ? h[len-2] : null;
    
        if( tld.length == 2 ) {
            if( only_gov && sld != 'gov' ) return null;
            switch(  ( tld.match(exceptionRe) || [null] )[0]  ) {
             case 'uk':
                //Britain owns+uses this one
                return 'gb';
             case 'ac':
                //Ascension Island is part of the British Overseas territory
                //"Saint Helena, Ascension and Tristan da Cunha"
                return 'sh';
             case null:
                //2-letter TLD *not* in the exception list;
                //it's a valid ccTLD corresponding to its country
                return tld;
             default:
                //2-letter TLD *in* the exception list (e.g.: .eu);
                //it's not a valid ccTLD and we don't know the country
                return null;
            }
        } else if( tld == 'gov' ) {
            //AMERICAAA
            return 'us';
        } else {
            return null;
        }
    }
    <p>Click the following domains:</p>
    <ul onclick="console.log(`${identifyCountry(event.target.textContent)} <= ${event.target.textContent}`);">
        <li>example.com</li>
        <li>example.co.uk</li>
        <li>example.eu</li>
        <li>example.ca</li>
        <li>example.ac</li>
        <li>example.gov</li>
    </ul>

    Honestly, though, you could just do something like

    function switchableMatch(s,r){
        //returns the FIRST match of r on s; otherwise, null
        const m = s.match(r);
        if(m) return m[0];
        else return null;
    }
    

    and then later switch(switchableMatch(s,r)){…}

    0 讨论(0)
提交回复
热议问题