RegExp.exec () NULL को छिटपुट रूप से लौटाता है


87

मैं गंभीरता से इस पर पागल हो रहा हूं और मैंने पहले से ही यह पता लगाने की कोशिश कर रहा है कि यहां क्या चल रहा है। इसलिए कृपया मुझे एक हाथ दें =)

मुझे जावास्क्रिप्ट में स्ट्रिंग्स के कुछ RegExp मिलान करने की आवश्यकता है। दुर्भाग्य से यह बहुत अजीब व्यवहार करता है। यह कोड:

var rx = /(cat|dog)/gi;
var w = new Array("I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.");

for (var i in w) {
    var m = null;
    m = rx.exec(w[i]);
    if(m){
        document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>");
    }else{
        document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>");
    }
}

पहले दो तत्वों के लिए "बिल्ली" और "कुत्ता" लौटाता है, जैसा कि यह होना चाहिए, लेकिन फिर कुछ- exec()कॉल वापस लौटने लगते हैं null। मुझे समझ में नहीं आता क्यों।

मैंने यहां एक फिडेल पोस्ट किया है , जहां आप कोड को चला सकते हैं और संपादित कर सकते हैं।

और अब तक मैंने क्रोम और फ़ायरफ़ॉक्स में इसकी कोशिश की है।

चीयर्स!

/ Christofer


यह केवल एक पर विफल रहता है "I have a cat and a dog too.", ऐसा लगता है
SilentGhost

यदि कोई मैच डिज़ाइन द्वारा विफल हो जाता है, तो रिटर्न रिटर्न निष्पादित करता है, इसलिए किसी कारण से यह मिलान करने में विफल रहता है।
मार्टिन जेस्परसन

जवाबों:


84

ओह, यह यहाँ है। क्योंकि आप अपने रेगेक्स ग्लोबल को परिभाषित कर रहे हैं, यह पहले से मेल खाता है cat, और लूप के दूसरे पास पर dog। तो, मूल रूप से आपको बस अपने regex (यह आंतरिक पॉइंटर) को रीसेट करना होगा। सी एफ यह:

var w = new Array("I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too.", "I have a cat and a dog too.");

for (var i in w) {
    var rx = /(cat|dog)/gi;
    var m = null;
    m = rx.exec(w[i]);
    if(m){
        document.writeln("<p>" + i + "<br/>INPUT: " + w[i] + "<br/>MATCHES: " + w[i].length + "</p>");
    }else{
        document.writeln("<p><b>" + i + "<br/>'" + w[i] + "' FAILED.</b><br/>" + w[i].length + "</p>");
    }
    document.writeln(m);
}

वहाँ हम यह है, मैं बहुत धीमी थी :)
मार्टिन Jespersen

आह मीठा! मुझे यह पता करने में थोड़ा समय लगा होगा कि कोई बाहर है। धन्यवाद!
cpak

इसने मुझे समय की बर्बादी से बचाया। बहुत बहुत धन्यवाद!
थॉमस जोहान्स

यह समस्या मुझे जीवन का संदेह बनाती है।
GZ Xue

मुझे ऐसा लगता है कि मुझे अपनी तनख्वाह वापस देनी चाहिए
cgatian

74

रेगेक्स ऑब्जेक्ट में एक गुण lastIndexहोता है जिसे आप चलाते समय अपडेट किया जाता है exec। इसलिए जब आप रेगेक्स को उदाहरण के लिए निष्पादित करते हैं "मेरे पास एक बिल्ली और एक कुत्ता भी है।", lastIndex12 पर सेट है। अगली बार जब आप execएक ही रेगेक्स ऑब्जेक्ट पर चलते हैं , तो यह सूचकांक 12 से दिखता है। इसलिए आपको lastIndexसंपत्ति रीसेट करनी होगी प्रत्येक रन के बीच में।


बाह, यह साइट मेरे लिए बहुत तेज़ है। साइलेंटहॉस्ट के लिए +1 :-)
फ्रॉड

10
स्पष्टीकरण के लिए धन्यवाद! यह myRe.lastIndex = 0;बाद के उपयोग के लिए सेट करके बहुत मदद करता है ।
एंटनी

1
वाह, lastIndex के साथ संकेत के लिए बहुत बहुत धन्यवाद, जो वास्तव में मुझे पागल कर रहा था!
dave0688

1
मुझे लगता है कि यह सही उत्तर होना चाहिए क्योंकि यह उसी रेगेक्स ऑब्जेक्ट के पुन: उपयोग की सर्वोत्तम प्रथा का अनुसरण करता है
स्मार्तघ

सहमत हूं कि यह सही उत्तर होना चाहिए। यह उसी रेगेक्स ऑब्जेक्ट का पुन: उपयोग करता है और आंतरिक यांत्रिकी को भी समझाता है। ओपी को बदलने पर विचार करना चाहिए।
सीन कॉले

34

दो चीज़ें:

  1. (वैश्विक) ध्वज का उपयोग करते समय रीसेट की उल्लिखित आवश्यकता g। इसे हल करने के लिए मैंने पुनः ऑब्जेक्ट 0के lastIndexसदस्य को असाइन किया RegExp। यह नष्ट-और-पुनः बनाने की तुलना में बेहतर प्रदर्शन है।
  2. किसी ऑब्जेक्ट को चलाने के लिए inकीवर्ड का उपयोग करतेArray समय सावधान रहें , क्योंकि कुछ परिवादों के साथ अप्रत्याशित परिणाम हो सकते हैं। कभी-कभी आपको किसी चीज़ की तरह जांच करनी चाहिए isNaN(i), या यदि आपको पता है कि इसमें छेद नहीं हैं, तो लूप के लिए क्लासिक का उपयोग करें।

कोड हो सकता है:

var rx = /(cat|dog)/gi;
w = ["I have a cat and a dog too.", "There once was a dog and a cat.", "I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat.","I have a cat and a dog too.", "There once was a dog and a cat."];

for (var i in w)
 if(!isNaN(i))        // Optional, check it is an element if Array could have some odd members.
  {
   var m = null;
   m = rx.exec(w[i]); // Run
   rx.lastIndex = 0;  // Reset
   if(m)
    {
     document.writeln("<pre>" + i + "\nINPUT: " + w[i] + "\nMATCHES: " + m.slice(1) + "</pre>");
    } else {
     document.writeln("<pre>" + i + "\n'" + w[i] + "' FAILED.</pre>");
    }
  }

1
यह सही उत्तर होना चाहिए। सेटिंग rx.lastIndex = 0लूप के अंदर RegEx ऑब्जेक्ट को फिर से बनाने से बहुत बेहतर है।
मिनोरू

4

मुझे केवल जी / जी का उपयोग करने में इसी तरह की समस्या थी, और यहां प्रस्तावित समाधान फायरफॉक्स 3.6.8 में मेरे लिए काम नहीं करता था। मुझे अपनी स्क्रिप्ट काम करने लगी

var myRegex = new RegExp("my string", "g");

मैं इस मामले में जोड़ रहा हूँ किसी और समस्या वही है जो मैंने उपरोक्त समाधान के साथ किया था।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.