web-dev-qa-db-ja.com

JavaScriptでの文字列照合用のswitchステートメント

次の条件付きのswtichを書くにはどうすればいいですか?

URL 含む "foo"の場合、settings.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/"
    };
}
168

あなたが完全な文字列マッチングをしていない限り、switchでそれを行うことはできません。それは部分文字列のマッチングをしています。 (これはまったくありませんSeanがコメントで指摘しているように、真です。最後の注を参照してください。]

あなたが一番上の正規表現があなたのマッチの中で比較したくないものすべてを取り除いて満足しているなら、あなたは部分文字列マッチを必要としません、そしてすることができます:

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

...しかし、繰り返しますが、それはcompleteがマッチする文字列である場合にのみ有効です。 base_url_stringが "yyy.xxx.local"の場合は失敗しますが、現在のコードは "xxx.local"ブランチのそれと一致します。


更新:さて、技術的にはあなたはcan部分文字列のマッチングにswitchを使うことができますが、ほとんどの場合はお勧めできません。 。その方法は次のとおりです( 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;
    }
}

JavaScript switchステートメントが動作する 、特に2つの重要な側面があるため、これは機能します。1つは、ケースがsource text orderで考慮されること、もう1つはセレクター式(キーワードcase)の後のビットはで、その場合に評価されます(他の言語のように定数ではありません)。テスト式はtrueなので、caseになる最初のtrue式が使用されることになります。

325
T.J. Crowder

RegExpは技術的にだけではなく実際にもmatchメソッドを使って入力文字列に使用できます。

match()の出力は配列なので、結果の最初の配列要素を取得する必要があります。一致が失敗すると、この関数はnullを返します。例外エラーを回避するために、最初の配列要素にアクセスする前に||条件演算子を追加し、正規表現の静的プロパティである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;
}

もう1つの方法は、String()コンストラクタを使用して、1つの要素のみを持ち(キャプチャグループはなし)、文字列全体を修飾子(.*)でキャプチャする必要がある配列を文字列に変換することです。失敗した場合、nullオブジェクトは"null"文字列になります。便利ではありません。

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

とにかく、もっと洗練された解決策は、単にブール値を返す/^find-this-in/.test(str)メソッドとswitch (true)メソッドを使うことです。大文字と小文字を区別せずに検索する方が簡単です。

49

Location.Hostプロパティを使うだけです

switch (location.Host) {
    case "xxx.local":
        settings = ...
        break;
    case "xxx.dev.yyy.com":
        settings = ...
        break;
}
34
Sean Kinsey

もう1つの選択肢は、 正規表現の一致結果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;
}
12
Mitar
var token = 'spo';

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


- >一致した場合、3項式は元のトークンを返します
---->元のトークンは大文字小文字の区別で評価されます

- >一致しなかった場合、3値は未定義を返します
----> Caseは未定義に対してトークンを評価しますが、これはうまくいけばあなたのトークンはそうではありません。

あなたの場合、三項検定は例えば何でもあり得る

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

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

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

3進表現です。

この場合のテストはtoken.match(/ spo /)で、トークンに保持されている文字列と正規表現/ spo /(この場合はリテラル文字列spo)が一致することを示します。

式と文字列が一致すると、結果はtrueになり、token(switch文が操作している文字列)が返されます。

明らかにtoken === tokenなのでswitch文がマッチし、大文字小文字が評価されます

レイヤで見ると、また、テストステートメントがテストの結果だけを見ることができるように、turneryテストがswitchステートメントの「前」に評価されることを理解した方が理解しやすいです。

3
Arcabard

それは簡単かもしれません。このように考えてみてください。

  • 最初に通常の文字の間の文字列を捉える
  • その後、 "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
3
Geery.S

手遅れかもしれませんが、ケース割り当てではこれが好きでした:)

function extractParameters(args) {
    function getCase(arg, key) {
        return arg.match(new RegExp(`${key}=(.*)`)) || {};
    }

    args.forEach((arg) => {
        console.log("arg: " + arg);
        let match;
        switch (arg) {
            case (match = getCase(arg, "--user")).input:
            case (match = getCase(arg, "-u")).input:
                userName = match[1];
                break;

            case (match = getCase(arg, "--password")).input:
            case (match = getCase(arg, "-p")).input:
                password = match[1];
                break;

            case (match = getCase(arg, "--branch")).input:
            case (match = getCase(arg, "-b")).input:
                branch = match[1];
                break;
        }
    });
};

あなたはそれをさらに取ることができ、オプションのリストを渡して|で正規表現を扱うことができます。

1
TacB0sS