it-swarm.com.de

Switch-Anweisung für String-Matching in JavaScript

Wie schreibe ich einen swtich für die folgende Bedingung?

Wenn die URL enthält "foo" ist, dann ist settings.base_url "bar".

Mit dem folgenden Befehl wird der erforderliche Effekt erzielt, aber ich habe das Gefühl, dass dies mit einem Switch leichter zu handhaben ist:

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

Sie können es nicht in einem switch tun, es sei denn, Sie führen einen vollständigen String-Abgleich durch. das macht Teilstring Matching.  (Das ist nicht ganz wahr, wie Sean in den Kommentaren betont. Siehe Hinweis am Ende.)

Wenn Sie froh sind, dass Ihr Regex an der Spitze alles entfernt, was Sie in Ihrem Match nicht vergleichen möchten, benötigen Sie kein Teilstring-Match und können Folgendes tun:

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

... aber auch das funktioniert nur, wenn dies die Zeichenfolge complete ist, die Sie abgleichen. Es würde scheitern, wenn base_url_string beispielsweise "yyy.xxx.local", während Ihr aktueller Code dem im Zweig "xxx.local" entsprechen würde.


Update : Okay, technisch gesehen können Sie können einen switch für den Teilstring-Abgleich verwenden, aber ich würde nicht kann es in den meisten Situationen nicht empfehlen. Hier ist, wie ( Live-Beispiel ):

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

Das liegt an der Funktionsweise von JavaScript switch Anweisungen , insbesondere an zwei Hauptaspekten: Erstens, dass die Fälle in der Reihenfolge Quelltext betrachtet werden, und zweitens, dass die Selektorausdrücke (die Bits nach dem Schlüsselwort case) Ausdrücke sind, die ausgewertet werden, während dieser Fall ausgewertet wird (keine Konstanten wie in einigen anderen Sprachen). Da unser Testausdruck also true ist, wird der erste case Ausdruck verwendet, der true ergibt.

330
T.J. Crowder

RegExp kann nicht nur technisch, sondern auch praktisch mit der Methode match für die Eingabezeichenfolge verwendet werden.

Da die Ausgabe von match() ein Array ist, müssen wir das erste Array-Element des Ergebnisses abrufen. Wenn die Übereinstimmung fehlschlägt, gibt die Funktion null zurück. Um einen Ausnahmefehler zu vermeiden, fügen wir vor dem Zugriff auf das erste Array-Element den Bedingungsoperator || Hinzu und testen ihn mit der Eigenschaft inputdas ist eine statische Eigenschaft regulärer Ausdrücke enthält die Eingabezeichenfolge.

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

Ein anderer Ansatz besteht darin, das resultierende Array mit dem Konstruktor String() zu konvertieren, das nur ein Element (keine Erfassungsgruppen) enthalten darf, und die gesamte Zeichenfolge mit Quanitifikatoren (.*) In eine Zeichenfolge zu konvertieren. Im Fehlerfall wird das Objekt null zu einer Zeichenfolge "null". Nicht bequem.

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

Eine elegantere Lösung ist die Verwendung der Methode /^find-this-in/.test(str) with switch (true), die einfach einen booleschen Wert zurückgibt und die Suche ohne Berücksichtigung der Groß-/Kleinschreibung vereinfacht.

50

Verwenden Sie einfach die Eigenschaft location.Host

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

Eine andere Option ist die Verwendung des input -Feldes eines reguläres Ergebnis :

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


-> Wenn die Übereinstimmung hergestellt wurde, gibt der ternäre Ausdruck das ursprüngliche Token zurück
----> Das ursprüngliche Token wird fallweise ausgewertet

-> Wenn die Übereinstimmung nicht hergestellt wird, gibt der Ternär undefiniert zurück
----> case wertet das Token mit undefined aus, was Ihr Token hoffentlich nicht ist.

Der ternäre Test kann in Ihrem Fall beispielsweise beliebig sein

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

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

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

ist ein ternärer Ausdruck.

In diesem Fall lautet der Test token.match (/ spo /) und gibt die Übereinstimmung der im Token enthaltenen Zeichenfolge mit dem regulären Ausdruck/spo/an (in diesem Fall ist dies die literale Zeichenfolge spo).

Wenn der Ausdruck und die Zeichenfolge übereinstimmen, ergibt sich true und es wird ein Token zurückgegeben (dies ist die Zeichenfolge, mit der die switch-Anweisung arbeitet).

Offensichtlich token === token, damit die switch-Anweisung übereinstimmt und der Fall ausgewertet wird

Es ist einfacher zu verstehen, wenn Sie es in Schichten betrachten und verstehen, dass der Dreher-Test "VOR" der switch-Anweisung ausgewertet wird, so dass die switch-Anweisung nur die Ergebnisse des Tests sieht.

4
Arcabard

Es könnte einfacher sein. Versuche so zu denken:

  • fange zuerst eine Zeichenkette zwischen regulären Zeichen
  • danach find "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

Könnte alles zu spät sein, aber mir gefiel das für den Fall der Zuweisung :)

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

sie könnten das Ereignis weiter verfolgen und eine Liste von Optionen übergeben und den regulären Ausdruck mit | behandeln

1
TacB0sS