在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
第一个case
expression式将被使用。
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