Polecenie Switch do dopasowania łańcuchów w JavaScript

Jak napisać swtich dla następującego warunku?

Jeśli url zawiera "foo" , to ustawienia.base_url to "bar".

Poniżej jest osiągnięcie wymaganego efektu, ale mam wrażenie, że byłoby to łatwiejsze do opanowania w przełączniku:

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/"
    };
}
Author: ST3, 2010-05-24

7 answers

nie możesz tego zrobić w switch, chyba że robisz pełne dopasowanie; to jest dopasowanie podciągu. (to nie jest całkiem prawda, jak zauważa Sean w komentarzach. Patrz notatka na końcu.)

Jeśli jesteś szczęśliwy, że Twój regex na górze usuwa wszystko, czego nie chcesz porównać w swoim meczu, nie potrzebujesz dopasowania fragmentu i możesz to zrobić: {]}

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

...ale znowu, to działa tylko wtedy, gdy jest to complete string you ' re matching. To by się nie udało, gdyby base_url_string było, powiedzmy, " yyy.xxx. local", podczas gdy twój obecny kod będzie pasował do tego w gałęzi "xxx. local".


Update : OK, więc technicznie można używać do dopasowywania podłańcuchów, ale nie polecałbym tego w większości sytuacji. Oto jak (przykład na żywo):

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

To działa ze względu na sposób JavaScript switch praca statements , w szczególności dwa kluczowe aspekty: Po pierwsze, że przypadki są rozpatrywane w kolejności tekst źródłowy , a po drugie, że wyrażenia selektora (bity po słowie kluczowym case) są wyrażeniami , które są oceniane tak, jak ten przypadek jest oceniany (a nie stałe jak w niektórych innych językach). Więc ponieważ nasze wyrażenie testowe to true, pierwsze case wyrażenie, które daje true będzie tym, które zostanie użyte.

 305
Author: T.J. Crowder,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-10-15 09:44:16

RegExp może być użyty na łańcuchu wejściowym nie tylko technicznie, ale i praktycznie za pomocą metody match.

Ponieważ wyjście match() jest tablicą, musimy pobrać pierwszy element tablicy wyniku. Gdy dopasowanie nie powiedzie się, funkcja zwraca null. Aby uniknąć błędu wyjątku, dodamy operator warunkowy || przed uzyskaniem dostępu do pierwszego elementu tablicy i przetestujemy właściwości input , które są statyczną właściwością wyrażeń regularnych, które zawiera łańcuch wejściowy.

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

Innym sposobem jest użycie konstruktora String() do konwersji wynikowej tablicy, która musi mieć tylko 1 element (bez grup przechwytywania) i cały łańcuch musi być przechwytywany za pomocą quanitifiers (.*) na łańcuch. W przypadku niepowodzenia obiekt null stanie się ciągiem znaków "null". To nie jest wygodne.

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

W każdym razie, bardziej eleganckim rozwiązaniem jest użycie metody /^find-this-in/.test(str) z switch (true), która po prostu zwraca wartość logiczną i łatwiej jest wyszukiwać bez wielkość liter.

 40
Author: Steven Pribilinskiy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-08 06:57:34

Po prostu użyj lokalizacji.host property

switch (location.host) {
    case "xxx.local":
        settings = ...
        break;
    case "xxx.dev.yyy.com":
        settings = ...
        break;
}
 34
Author: Sean Kinsey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-05-24 11:38:35

Inną opcją jest użycie pola {[1] } z regexp match result :

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;
}
 10
Author: Mitar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-25 01:36:49
var token = 'spo';

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


--> Jeśli dopasowanie zostanie wykonane, wyrażenie trójskładnikowe zwróci oryginalny token
----> oryginalny token jest oceniany przez case

-- > Jeśli dopasowanie nie jest wykonane, Trójnik zwraca undefined
----> Case ocenia token na undefined, który, miejmy nadzieję, nie jest Twoim tokenem.

Test trójkowy może być dowolny, na przykład w Twoim przypadku

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

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

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

Jest wyrażeniem trójdzielnym.

Test w tym przypadku jest token.match (/spo/), który określa dopasowanie łańcucha przechowywanego w tokenie do wyrażenia regex/ spo / (które w tym przypadku jest literalnym łańcuchem spo).

Jeśli wyrażenie i łańcuch są zgodne, to powoduje to true i zwraca token(który jest łańcuchem, na którym operuje Instrukcja switch).

Oczywiście token = = = token więc polecenie switch jest dopasowane i wielkość liter

Jest łatwiej zrozumieć, jeśli spojrzeć na to w warstwy i zrozumieć, że test turnery jest oceniany "przed" instrukcją switch tak, że instrukcja switch widzi tylko wyniki testu.

 3
Author: Prospero,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-18 15:36:36

Może być łatwiej. Spróbuj tak myśleć:

  • najpierw Złap łańcuch pomiędzy zwykłymi znakami
  • po tym znajdź "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
 2
Author: Geery.S,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-18 10:23:10

Może być za późno i w ogóle, ale mi się to podobało w przypadku:)

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

Event może pójść dalej, przekazać listę opcji i obsłużyć regex za pomocą /

 0
Author: TacB0sS,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-15 12:03:00