जावास्क्रिप्ट Regexp में समूहों की एक मनमानी संख्या पर कब्जा कैसे करें?


84

मैं जावास्क्रिप्ट की इस लाइन की उम्मीद करूंगा:

"foo bar baz".match(/^(\s*\w+)+$/)

कुछ वापस करने के लिए जैसे:

["foo bar baz", "foo", " bar", " baz"]

लेकिन इसके बजाय यह केवल अंतिम कैप्चर किए गए मैच को लौटाता है:

["foo bar baz", " baz"]

क्या सभी पकड़े गए मैचों को प्राप्त करने का एक तरीका है?

जवाबों:


93

जब आप एक कैप्चरिंग ग्रुप को दोहराते हैं, तो ज्यादातर फ्लेवर में, केवल आखिरी कैप्चर को रखा जाता है; किसी भी पिछले कैप्चर को ओवरराइट किया गया है। कुछ स्वाद में, उदाहरण के लिए .NET, आप सभी मध्यवर्ती कैप्चर प्राप्त कर सकते हैं, लेकिन जावास्क्रिप्ट के साथ ऐसा नहीं है।

यही है, जावास्क्रिप्ट में, यदि आपके पास एन कैप्चरिंग समूहों के साथ एक पैटर्न है , तो आप केवल प्रति मैच बिल्कुल एन स्ट्रिंग्स पर कब्जा कर सकते हैं , भले ही उन समूहों में से कुछ को दोहराया गया हो।

तो आम तौर पर बोल, तुम क्या करने की जरूरत पर निर्भर करता है:

  • यदि यह एक विकल्प है, तो इसके बजाय सीमांकक पर विभाजित करें
  • मिलान के बजाय /(pattern)+/, शायद मेल खाए /pattern/g, शायद एक execपाश में
    • ध्यान दें कि ये दोनों बिल्कुल समान नहीं हैं, लेकिन यह एक विकल्प हो सकता है
  • बहुस्तरीय मिलान करें:
    • एक मैच में दोहराया समूह पर कब्जा
    • फिर उस मैच को तोड़ने के लिए एक और regex चलाएं

संदर्भ


उदाहरण

यहाँ <some;words;here>एक पाठ में मेल का एक उदाहरण है , एक execलूप का उपयोग करना , और फिर अलग ;-अलग शब्दों को प्राप्त करने के लिए विभाजन करना ( ideone.com पर भी देखें ):

var text = "a;b;<c;d;e;f>;g;h;i;<no no no>;j;k;<xx;yy;zz>";

var r = /<(\w+(;\w+)*)>/g;

var match;
while ((match = r.exec(text)) != null) {
  print(match[1].split(";"));
}
// c,d,e,f
// xx,yy,zz

इस्तेमाल किया पैटर्न है:

      _2__
     /    \
<(\w+(;\w+)*)>
 \__________/
      1

यह मैचों <word>, <word;another>, <word;another;please>, आदि समूह 2 शब्द के किसी भी संख्या पर कब्जा करने के दोहराया है, लेकिन यह केवल पिछले कब्जा रख सकते हैं। शब्दों की पूरी सूची समूह 1 द्वारा कैप्चर की गई है; यह स्ट्रिंग splitअर्धवृत्ताकार सीमांकक पर है।

संबंधित सवाल


7

यह कैसे हुआ? "foo bar baz".match(/(\w+)+/g)


आपका कोड काम करता है, लेकिन मेरे उदाहरण में एक वैश्विक ध्वज जोड़ने से समस्या हल नहीं होगी: "फू बार बाज" (। ^ (\ _ * \ W + +) + $ / g) वापस आ जाएगा ["फू बार बाज"]
डिस्को डांसर

यदि आप इसे नीचे @ Jet की नियमित अभिव्यक्ति में बदलते हैं तो यह काम करेगा। "foo bar baz".match(/\w+/g) //=> ["foo", "bar", "baz"]। यह मोर्चे पर मिलान स्ट्रिंग की उपेक्षा करता है, लेकिन अभी भी एक उचित विकल्प है।
जेड श्नाइडर

6

जब तक आपके पास आपके स्ट्रिंग्स को विभाजित करने के लिए अधिक जटिल आवश्यकता नहीं होती है, आप उन्हें विभाजित कर सकते हैं, और फिर उनके साथ प्रारंभिक स्ट्रिंग वापस कर सकते हैं:

var data = "foo bar baz";
var pieces = data.split(' ');
pieces.unshift(data);

1
यह सिर्फ सलाह का टुकड़ा होने के कारण मुझे समाप्त हो गया, मुझे इस तथ्य के प्रति जागृत करने की आवश्यकता थी कि, मेरे वर्तमान आवेदन के लिए, मुझे विभाजन से अधिक परिष्कृत कुछ भी नहीं चाहिए था ()।
हेफेस्टस

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