我如何为以下条件写一个开关?

如果url包含“foo”,则设置。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/"
    };
}

当前回答

这可能更容易。试着这样想:

首先捕获常规字符之间的字符串 然后找到"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

其他回答

独立版本,增加工作安全性:

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>

说实话,你可以做一些

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

然后切换(switchableMatch(s,r)){…}

使用位置即可。主机属性

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

你也可以像这样使用默认的情况:

    switch (name) {
        case 't':
            return filter.getType();
        case 'c':
            return (filter.getCategory());
        default:
            if (name.startsWith('f-')) {
                return filter.getFeatures({type: name})
            }
    }

除非你在做全字符串匹配,否则你不能在开关中这么做;这是在做子字符串匹配。(正如Sean在评论中指出的那样,这并不完全正确。见末尾注释。)

如果你很高兴你的正则表达式在顶部剥离了所有你不想在你的匹配中比较的东西,你不需要一个子字符串匹配,可以这样做:

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

...但同样,这只适用于你匹配的完整字符串。如果base_url_string是“yyy.xxx”,则会失败。而您当前的代码将与“xxx. Local”中的匹配。本地”分支。


更新:好的,所以技术上你可以使用开关进行子字符串匹配,但我不建议在大多数情况下。以下是如何做到的(活生生的例子):

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是按照源文本的顺序考虑的,其次,选择器表达式(关键字case后面的位)是在case计算时计算的表达式(而不是像其他一些语言中的常量)。既然我们的测试表达式为真,那么第一个结果为真的case表达式就会被使用。

如果需要使用正则表达式,请为开关情况创建一个带有正则表达式和条件响应的对象

let test = (str) => {
    let obj = {
        'foo':'bar',
        '\/albums?':'photo'
    };
    for(let prop in obj){
        if(new RegExp(prop).test(str))return obj[prop]
    };
};

switch(test(location.href)){
    case 'bar':
        console.log('url has bar')
    break;
}