2012-02-09 13 views
89

अगर मैं रन:RegExp के exec() फ़ंक्शन और स्ट्रिंग के मिलान() फ़ंक्शन के बीच क्या अंतर है?

/([^\/]+)+/g.exec('/a/b/c/d'); 

मैं इस मिल:

["a", "a"] 

लेकिन अगर मैं इस चलाएँ:

: मैं इस के अपेक्षित परिणाम प्राप्त

'/a/b/c/d'.match(/([^\/]+)+/g); 

फिर

["a", "b", "c", "d"] 

क्या अंतर है?

+2

आप सभी उप-चयन प्राप्त करने के लिए 'exec' के साथ लूप करते हैं। – zzzzBov

+2

ध्यान दें कि दूसरा '+' की आवश्यकता नहीं है क्योंकि 'मिलान' पहले से ही सभी उप-अभिव्यक्तियों को वापस कर देगा। '.exec' प्रत्येक बार केवल एक लौटाता है, इसलिए इसे '+' की आवश्यकता नहीं होती है। – pimvdb

+3

उस के शीर्ष पर, दो प्लस की तरह नेस्टेड क्वांटिफ़ायर का उपयोग बहुत सावधानीपूर्वक किया जाना चाहिए क्योंकि वे आसानी से [आपदाजनक बैकट्रैकिंग] (http://www.regular-expressions.info/catastrophic.html) का नेतृत्व करते हैं। –

उत्तर

89

exec वैश्विक नियमित अभिव्यक्ति के साथ एक लूप में उपयोग किया जाना है, क्योंकि यह अभी भी सभी मिलान किए गए उप-अभिव्यक्तियों को पुनर्प्राप्त करेगा। तो:

var re = /[^\/]+/g; 
var match; 

while (match = re.exec('/a/b/c/d')) { 
    // match is now the next match, in array form. 
} 

// No more matches. 

String.match यह आपके लिए करता है और कब्जे वाले समूहों को त्याग देता है।

+15

मेरे पास इस उत्तर में जोड़ने के लिए कुछ है, किसी को समय की स्थिति में नियमित अभिव्यक्ति शाब्दिक नहीं रखना चाहिए, जैसे कि 'while (match = /[^\/]+/g.exec('/a/b/c/ डी ')' या यह एक अनंत लूप बनाएगा! जैसा कि यह स्पष्ट रूप से एमडीएन https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec – yeyo

+3

@yeyo में स्पष्ट रूप से बताया गया है : अधिक विशेष रूप से, यह एक ही नियमित अभिव्यक्ति वस्तु होना चाहिए। एक शाब्दिक इसे पूरा नहीं करता है। – Ryan

21

/regex/.exec() केवल पहला मैच मिला, जबकि "string".match() यदि आप g रेगेक्स में ध्वज का उपयोग करते हैं तो उन सभी को वापस कर देता है।

यहां देखें: exec, match

54

एक चित्र बेहतर क्या आप जानते है, ...

re_once = /([a-z])([A-Z])/ 
 
re_glob = /([a-z])([A-Z])/g 
 

 
st = "aAbBcC" 
 

 
console.log("match once="+ st.match(re_once)+ " match glob="+ st.match(re_glob)) 
 
console.log("exec once="+ re_once.exec(st) + " exec glob="+ re_glob.exec(st)) 
 
console.log("exec once="+ re_once.exec(st) + " exec glob="+ re_glob.exec(st)) 
 
console.log("exec once="+ re_once.exec(st) + " exec glob="+ re_glob.exec(st))

अंतर देखते हैं?

नोट: बताने के लिए, सूचना है कि समूहों पर कब्जा कर लिया (जैसे: एक, ए) का मिलान नहीं हुआ पैटर्न के बाद लौटा दिया जाता है (जैसे: एए), यह न सिर्फ मिलान किया पैटर्न है।

+0

मुझे पता है कि हमें इस तरह की टिप्पणियां नहीं करनी चाहिए, लेकिन यह एक उत्कृष्ट जवाब है! मैं इसे सहेजने जा रहा हूं । – Joe

15

यदि आपका रेगेक्स वैश्विक है, और आप कैप्चरिंग कर रहे हैं, तो आपको exec का उपयोग करना होगा। मैच आपके सभी कैप्चर वापस नहीं करेगा।

मैच मिलान करने (कैप्चरिंग) के लिए बहुत अच्छा काम करता है। आप इसे एक बार चलाते हैं और यह सभी मैचों की एक सरणी देता है। (हालांकि यदि रेगेक्स वैश्विक नहीं है, तो मैच कैप्चर के बाद मैच दिखाएगा)

Exec वह है जो आप कैप्चर करते समय उपयोग करते हैं, और प्रत्येक बार जब इसे निष्पादित किया जाता है तो यह मैच को कैप्चर करता है। (मैच पूरी तरह से कैप्चर के बाद पूरा मैच देने के तरीके से व्यवहार करेगा, केवल जब रेगेक्स वैश्विक नहीं है)।

एक्सेक के साथ एक और उपयोग, एक मैच के सूचकांक या स्थिति प्राप्त कर रहा है। जब आपके रेगेक्स के लिए एक चर हो, तो आप .lastIndex का उपयोग कर सकते हैं और मिलान की स्थिति प्राप्त कर सकते हैं। एक रेगेक्स ऑब्जेक्ट में .lastIndex है, और regex ऑब्जेक्ट वह है जो आप करते हैं। Exec चालू। डॉट मैच एक स्ट्रिंग पर किया जाता है और आप फिर से regex ऑब्जेक्ट डॉट करने में सक्षम नहीं होंगे अंतिम इंडेक्स

एक स्ट्रिंग में मिलान फ़ंक्शन होता है, जिसे रेगेक्स पास किया जाता है। और एक regex, निष्पादन समारोह है, और एक स्ट्रिंग

निष्पादन पारित किया जाता है जिसे आप कई बार चलाते हैं।एक बार

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

> "azb".match(/a(z)b/); 
[ "azb", "z" ] 

> "azb".match(/a(z)b/g); 
[ "azb" ] 
> 

एक और बात है कि अगर आप कार्यकारी का उपयोग, ध्यान दें कि regex पर कहा जाता है फिर अगर आप रेगुलर एक्सप्रेशन के लिए एक चर का इस्तेमाल किया है, तो आप और अधिक शक्ति है

आप मैचों जब तुम नहीं मिलता जब कार्यकारी का उपयोग कर regex के लिए चर का उपयोग नहीं है, इसलिए regex, के लिए चर का उपयोग

> /./g.exec("abc") 
[ "a" ] 
> /./g.exec("abc") 
[ "a" ] 
> /./g.exec("abc") 
[ "a" ] 
> 
> /[a-c]/g.exec("abc") 
[ "a" ] 
> /[a-c]/g.exec("abc") 
[ "a" ] 
> 

> var r=/[a-c]/g 
> r.exec("abc") 
[ "a" ] 
> r.exec("abc") 
[ "b" ] 
> r.exec("abc") 
[ "c" ] 
> r.exec("abc") 
null 
> 

और कार्यकारी के साथ, आप मैच के "अनुक्रमणिका" प्राप्त कर सकते हैं

> var r=/T/g 
> r.exec("qTqqqTqqTq"); 
[ "T" ] 
> r.lastIndex 
2 
> r.exec("qTqqqTqqTq"); 
[ "T" ] 
> r.lastIndex 
6 
> r.exec("qTqqqTqqTq"); 
[ "T" ] 
> r.lastIndex 
9 
> r.exec("qTqqqTqqTq"); 
null 
> r.lastIndex 
0 
> 

तो यदि आप इंडेक्स या कैप्चरिंग चाहते हैं, तो निष्पादन का उपयोग करें (ध्यान रखें कि जैसा कि आप "इंडेक्स" के साथ देख सकते हैं, "इंडेक्स" यह वास्तव में एक nth घटना है, यह 1 से गिन रहा है। तो आप कर सकते हैं घटाकर 1 से घटाकर उचित इंडेक्स प्राप्त करें। और जैसा कि आप देख सकते हैं कि यह 0 - अंतिम इंडेक्स 0 - नहीं मिला है)।

और यदि आप मैच खींचना चाहते हैं, तो आप इसे कैप्चर करते समय इसका उपयोग कर सकते हैं, लेकिन जब रेगेक्स वैश्विक नहीं है, और जब आप इसके लिए ऐसा करते हैं, तो सरणी की सामग्री सभी मैचों नहीं होती है, लेकिन कैप्चर के बाद पूरा मैच है।

संबंधित मुद्दे