在JavaScript中用于string匹配的switch语句

如何为以下条件写一个swtich?

如果url 包含 “foo”,那么settings.base_url是“bar”。

以下是达到所需的效果,但我有一种感觉,这将是一个开关更易于pipe理:

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

除非你正在进行string匹配,否则你不能在switch执行它。 这是做子string匹配。 (这是不 正确的,正如肖恩在评论中指出的那样,最后见注)。

如果你很高兴你的正则expression式正在剥离你不想在比较中进行比较的所有东西,那么你不需要一个子string匹配,并且可以这样做:

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

…但是再一次,只有这是你匹配的完整string才有效。 如果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语句的工作方式 ,特别是两个关键方面:首先,以源文本顺序考虑情况,其次select器expression式(关键字case之后的位)是被评估为案件被评估(不像其他一些语言中的常量)。 所以,既然我们的testingexpression式是true ,那么结果为true第一个caseexpression式将被使用。

RegExp可以在inputstring上使用,不仅在技术上,而且在match方法上也是如此。

由于match()的输出是一个数组,我们需要检索结果的第一个数组元素。 当匹配失败时,函数返回null 。 为避免exception错误,我们将添加|| 在访问第一个数组元素之前使用条件运算符,并对input属性进行testing,该属性是包含inputstring的正则expression式的静态属性 。

 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()构造函数转换必须只有1个元素(不捕获组)的结果数组,并且必须使用量化符( .* )将整个string捕获到string中。 如果发生故障, null对象将变成"null"string。 不方便。

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

无论如何,一个更优雅的解决scheme是使用switch (true)方法使用/^find-this-in/.test(str) ,它只是简单地返回一个布尔值,而且在没有区分大小写的情况下更容易search。

只需使用location.host属性

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

另一种select是使用正则expression式匹配结果的 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; } 
 var token = 'spo'; switch(token){ case ( (token.match(/spo/) )? token : undefined ) : console.log('MATCHED') break;; default: console.log('NO MATCH') break;; } 

– >如果匹配成立,则三元expression式返回原始标记
—->原始标记按大小写评估

– >如果不匹配,则三元返回未定义
—->案例评估对未定义的令牌,希望你的令牌不是。

三元testing可以是任何例如你的情况

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

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

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

是一个三元的expression。

在这种情况下,testing是token.match(/ spo /),它表示匹配正则expression式/ spo /(在这种情况下是字面值stringspo)中的令牌string。

如果expression式和string匹配,则返回true,并返回token(这是switch语句操作的string)。

显然,令牌===令牌,所以switch语句匹配,并评估的情况下

如果你仔细看看它,并且理解turntrytesting是在switch语句的“BEFORE”之前进行评估的,这样switch语句只能看到testing的结果,那么理解起来会更容易一些。

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

  • 先在常规字符之间捕捉一个string
  • 之后find“案例”

 // '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