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

如果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/"
    };
}

当前回答

另一种选择是使用regexp匹配结果的输入字段:

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

其他回答

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

首先捕获常规字符之间的字符串 然后找到"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 (name) {
        case 't':
            return filter.getType();
        case 'c':
            return (filter.getCategory());
        default:
            if (name.startsWith('f-')) {
                return filter.getFeatures({type: name})
            }
    }

RegExp也可以用match方法用于输入字符串。

为了确保在case子句中有匹配,我们将根据成功匹配的输入属性测试原始str值(提供给switch语句的值)。

Input是正则表达式的静态属性,包含原始输入字符串。

当匹配失败时,它返回null。为了避免异常错误,我们在访问输入属性之前使用可选的链接操作符(或传统ES中的逻辑||条件操作符)。

const 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'字符串。这似乎不太方便。

const str = 'XYZ test';

switch (str.toLowerCase()) {
  case String(str.match(/^xyz.*/i)):
    console.log("Matched a string without case sensitivity");
    break;
  case String(str.match(/.*tes.*/)):
    console.log("Matched a string using a substring 'tes'");
    break;
}

不管怎样,一个更优雅的解决方案是使用test方法而不是match,即/^find-this-in/.test(str)与switch (true),它只是返回一个布尔值,并且更容易匹配,不区分大小写。

const str = 'haystack';

switch (true) {
  case /^hay.*/i.test(str):
    console.log("Matched a string that starts with 'hay'");
    break;
}

然而,在这种情况下使用if else else if语句也是可读的

var token = 'spo';

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

——>如果匹配成功,三元表达式返回原始令牌 ---->原始令牌按大小写计算

——>如果没有匹配,三元返回undefined ----> Case对未定义的令牌进行计算,希望您的令牌不是。

三元测试可以是任何东西,例如在你的例子中

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

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

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

三元表达式。

本例中的测试是token.match(/spo/),它声明token中包含的字符串与正则表达式/spo/(在本例中是字面字符串spo)的匹配。

如果表达式和字符串匹配,则返回true并返回token(这是switch语句正在操作的字符串)。

显然,token === token可以匹配switch语句并计算case

如果你在层中看它,并理解翻转测试是在switch语句之前求值的,因此switch语句只看到测试的结果,这就更容易理解了。

除非你在做全字符串匹配,否则你不能在开关中这么做;这是在做子字符串匹配。(正如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表达式就会被使用。