जावास्क्रिप्ट में स्ट्रिंग मिलान के लिए स्विच स्टेटमेंट


193

निम्नलिखित स्थिति के लिए मैं एक swtich कैसे लिख सकता हूं?

यदि url में "foo" है, तो settings.base_url "बार" है।

निम्नलिखित आवश्यक प्रभाव प्राप्त कर रहा है, लेकिन मुझे लगता है कि यह एक स्विच में अधिक प्रबंधनीय होगा:

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

जवाबों:


352

switchजब तक आप पूर्ण स्ट्रिंग मिलान नहीं कर रहे हैं आप इसे नहीं कर सकते ; यह सबस्टेशन मिलान कर रहा है । (यह काफी सच नहीं है, जैसा कि शॉन टिप्पणियों में बताते हैं। नोट को अंत में देखें।)

यदि आप खुश हैं कि शीर्ष पर आपका रेगेक्स वह सब कुछ छीन रहा है जो आप अपने मैच में तुलना नहीं करना चाहते हैं, तो आपको एक विकल्प मैच की आवश्यकता नहीं है, और यह कर सकते हैं:

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

... लेकिन फिर, यह केवल तभी काम करता है जब आप पूरी स्ट्रिंग का मिलान कर रहे हों। यदि 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;
    }
}

इस तरह से काम करता है क्योंकि जावास्क्रिप्ट switchस्टेटमेंट काम करता है , विशेष रूप से दो प्रमुख पहलुओं में: पहला, कि मामलों को स्रोत पाठ क्रम में माना जाता है , और दूसरा यह कि चयनकर्ता अभिव्यक्तियाँ (कीवर्ड के बाद बिट्स case) अभिव्यक्ति हैं जो उस स्थिति के रूप में मूल्यांकन की जाती हैं मूल्यांकन किया गया (कुछ अन्य भाषाओं की तरह नहीं)। इसलिए जब से हमारी परीक्षा की अभिव्यक्ति है true, पहली caseअभिव्यक्ति जो परिणाम देती है trueवह वही होगी जिसका उपयोग किया जाता है।


91
मुझे पता है कि यह पुराना है, लेकिन यह बिल्कुल सच नहीं है - आप वास्तव में कर सकते हैंswitch(true) { case /foo/.test(bar): ....
शॉन किन्से

23
हे भगवान, नहीं! स्विच स्टेटमेंट को इस तरह काम नहीं करना चाहिए। यह बस टूट गया है, इस तरह से सामान करना अवैध होना चाहिए।
पीजूस

47
होहु, इतनी स्वादिष्ट बुराई।
आदित्य एमपी

41
आप सभी को अपने दृष्टिकोण को व्यापक बनाने की जरूरत है। रूबी में यह आदर्श है, trueवहां बदसूरत होने के अलावा , आप बस इसे एक साथ छोड़ देते हैं।
Emkman

49
मुझे यह पसंद है और मुझे इसे स्वीकार करने में कोई शर्म नहीं है।
क्रिस्चियन

65

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

एक अन्य तरीका यह है कि 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)जो बस एक बूलियन मूल्य देता है और केस संवेदनशीलता के बिना खोज करना आसान है।


1
pribilinsiky: आपको शायद यह उल्लेख करना चाहिए कि आपके तीसरे समाधान (परीक्षण () का उपयोग करके) के लिए आपको स्विच (सत्य) की आवश्यकता है।
ट्रेन्ड

35

बस location.host प्रॉपर्टी का उपयोग करें

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

1
धन्यवाद, +1 इस रूप में कि मुझे वास्तव में क्या करना चाहिए
डॉ। फ्रैंकनस्टाइन

आपको स्विच स्टेटमेंट को पास करने वाले चर प्रकार के बारे में ध्यान रखना होगा। यह एक तार होना चाहिए। यह सुनिश्चित करने के लिए कि आप कर सकते हैं switch ("" + location.host)
15:11 बजे

16

एक अन्य विकल्प inputएक regexp मैच परिणाम के क्षेत्र का उपयोग करना है :

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

अच्छा है। इस मामले में किसी भी सरणी संपत्ति का उपयोग परीक्षण के लिए भी किया जा सकता है, जैसे.length:
स्टीवन प्रिबिलिनस्की 11

6
var token = 'spo';

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


-> यदि मैच को टर्नरी अभिव्यक्ति बनाया जाता है तो मूल टोकन
----> मूल टोकन का मूल्यांकन केस द्वारा किया जाता है

-> यदि मैच को टर्नरी रिटर्न अपरिभाषित नहीं बनाया जाता है
----> मामला अपरिभाषित के खिलाफ टोकन का मूल्यांकन करता है जो उम्मीद करता है कि आपका टोकन नहीं है।

उदाहरण के लिए आपके मामले में टर्नरी परीक्षण कुछ भी हो सकता है

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

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

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

एक ternary अभिव्यक्ति है।

इस मामले में परीक्षण token.match (/ spo /) है, जो मैच को regex अभिव्यक्ति / spo / (जो इस मामले में शाब्दिक स्ट्रिंग को खराब करता है) के विरुद्ध टोकन में आयोजित स्ट्रिंग बताता है।

यदि अभिव्यक्ति और स्ट्रिंग मेल खाते हैं तो यह सच है और टोकन लौटाता है (जो स्ट्रिंग स्टेटमेंट चालू है)।

स्पष्ट रूप से टोकन === टोकन इसलिए स्विच स्टेटमेंट का मिलान किया जाता है और मामले का मूल्यांकन किया जाता है

इसे समझना आसान है अगर आप इसे परतों में देखते हैं और समझते हैं कि टर्नरी परीक्षण का मूल्यांकन "BEFORE" स्विच स्टेटमेंट से किया जाता है ताकि स्विच स्टेटमेंट केवल परीक्षण के परिणामों को देखे।


आपका जवाब भ्रमित करने वाला है। क्या आप उदाहरण और स्पष्टीकरण की समीक्षा और सुधार कर सकते हैं?
falsarella

@falsarella मैंने आपको जिस भाग की कल्पना की, उसे समझने में परेशानी हुई। मुझे नहीं लगता कि मैं एक सरल उदाहरण बना सकता हूं। यदि आपके पास अधिक प्रश्न हैं या आपकी कठिनाइयों के साथ अधिक विशिष्ट हो सकता है तो मैं और अधिक मदद कर सकता हूं।
जेम्स

ठीक है, अब मैं समझ गया। मैं उलझन में था क्योंकि यह स्पष्ट है कि token.match(/spo/)मैच होगा।
falsarella

3

यह आसान हो सकता है। इस तरह सोचने की कोशिश करें:

  • पहले नियमित पात्रों के बीच एक स्ट्रिंग पकड़ें
  • उसके बाद "केस" ढूंढें

:

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

Upvoted। लेकिन ध्यान दें:TypeError: url.match(...) is null
2:11 बजे 1111161171159459134

1

बहुत देर हो सकती है और सभी, लेकिन मुझे यह मामला असाइनमेंट में पसंद आया :)

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

आप इसे आगे ले जा सकते हैं, और विकल्प की सूची पास कर सकते हैं और regex को संभाल सकते हैं |


1
मैं भी बदल जाएगा || {}करने के लिए || [-1]या प्रकार की सुरक्षा के लिए इसी तरह की। इसके अलावा, new RegExpसिर्फ स्लैश ही क्यों, इसका इस्तेमाल किया जाता है?
सेर्गेई कैसिलिलनिकोव

वास्तव में इसे परिष्कृत करने के लिए समय नहीं लिया गया .. जिस पल यह काम किया मैंने अभी जारी रखा ..... मुझे अब शर्म आती है।
TacB0sS

घबराओ मत, यह सिर्फ मेरी नाइट-पिकिंग थी;) वास्तव में मुझे यकीन नहीं है कि मैं सही हूं, मैंने नया सीखने की कोशिश की।
सेर्गेई कसीसिलनिकोव

नहीं ... आप सही हैं ... मैं निश्चित रूप से जनरेट और प्रीटेट कर सकता था .. जब मैं दोबारा उस कोड में आऊंगा .. तो जल्द ही मुझे उम्मीद होगी :)
TacB0sS
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.