2011-03-02 16 views
12

मान लीजिए कि हम निम्न पाठ डालते हैं: "1 एक, 2 बी, 3 सी, 4 डी" और निम्नलिखित अभिव्यक्ति:/\ घ (\ डब्ल्यू)/जीजावास्क्रिप्ट नियमित अभिव्यक्ति इटरेटर को निकालने के लिए समूहों

क्या हम नियमित अभिव्यक्ति द्वारा बताए गए ए, बी, सी, डी निकालने के लिए करना चाहते हैं।

दुर्भाग्य से "1 ए, 2 बी, 3 सी, 4 डी"। मैच (/ \ d (\ w)/g) एक सरणी उत्पन्न करेगा: 1 ए, 2 बी, 3 सी, 4 डी और RegExp। $ 1 में केवल अंतिम मैच के समूह होंगे, यानी RegExp। $ 1 == 'डी'।

कैसे मैं भी इस regex से अधिक पुनरावृति करूँ ताकि समूहों निकाल सकते हैं ... मैं एक समाधान भी स्मृति कुशल है, यानी इटरेटर वस्तु के कुछ प्रकार

संपादित रहा हूँ: यह की जरूरत है सामान्य होना मैं केवल यहां एक साधारण उदाहरण प्रदान कर रहा हूं। एक समाधान सरणी पर लूप करना है और वैश्विक ध्वज के बिना प्रत्येक आइटम के लिए रेगेक्स को दोबारा लागू करना है, लेकिन मुझे यह समाधान थोड़ा बेवकूफ लगता है हालांकि ऐसा करने का एकमात्र तरीका लगता है।

+3

अपने हाल के प्रश्नों को स्वीकार करें। – hsz

+1

क्या इसे रेगेक्स होना चाहिए? आप रिक्त स्थान और अल्पविरामों पर भी विभाजित हो सकते हैं और उस तरह से निकालेंगे। – pimvdb

+0

हां, क्योंकि मैं केवल एक साधारण उदाहरण प्रदान कर रहा हूं ... यह इससे अधिक जटिल है। एक समाधान सरणी में प्रत्येक मैच के लिए रेगेक्स को फिर से लागू करना है, लेकिन यह सिर्फ बेवकूफ – Pass

उत्तर

12
var myregexp = /\d (\w)/g; 
var match = myregexp.exec(subject); 
while (match != null) { 
    // matched text: match[0] 
    // match start: match.index 
    // capturing group n: match[n] 
    match = myregexp.exec(subject); 
} 

(बेशर्म RegexBuddy से लिया गया)

+0

मुझे यह बिल्कुल नहीं मिलता है। मैच केवल 1 ए, 2 बी, 3 सी इत्यादि जैसे सभी तत्वों की एक सरणी है ... हम कैप्चरिंग समूहों को तब तक नहीं निकाल सकते जब तक कि रेगेक्स का पुन: उपयोग नहीं किया जाता है या ऐसा करने के लिए एपीआई है ... – Pass

+0

@Pass - जब नहीं आप 'exex' - मिलान का उपयोग पूरे मैच को पहले तत्व के रूप में, और प्रत्येक समूह को अन्य तत्वों के रूप में शामिल करेंगे, उदाहरण के लिए,' ['1 ए', 'ए'] ' – Kobi

+0

'मिलान [0]' पूरा मिलान है (उदाहरण के लिए '1 ए'); 'मैच [1] 'पहला कैप्चरिंग समूह (' ए') है। यह स्ट्रिंग पर पुनरावृत्त होता है ('जबकि' ब्लॉक की अंतिम पंक्ति देखें)। –

1

यह काम करेंगे:

"1 a,2 b,3 c,4 d".match(/\w(?:,|$)/g).join(' '); // => "a, b, c, d" 

आप पुनरावृति करने की आवश्यकता है, तो:

var r = /\d (\w)/g, 
    s = "1 a,2 b,3 c,4 d", 
    m; 

while (m = r.exec(s)) { 
    // `m` is your match, `m[1]` is the letter 
} 
+0

सुझाव के लिए धन्यवाद है लेकिन उदाहरण बहुत विशिष्ट है .. मैं एक सामान्य समाधान की तलाश में हूं क्योंकि मेरा वास्तविक कोड अधिक जटिल नियमित अभिव्यक्तियों का उपयोग करता है – Pass

+0

@ पैस, लूप देखें। – James

+0

बहुत बहुत धन्यवाद ... यह ठीक काम करता है – Pass

2

एक छोटा, सरल (हालांकि संभावित कम कुशल) समाधान String.prototype.replace का उपयोग करना है। प्रतिस्थापित अद्वितीय है कि यह सभी मैचों पर पूरी तरह से पुनरावृत्त करता है और प्रत्येक मैच के लिए फ़ंक्शन निष्पादित करता है। बेशक, आप उपयोग है कि वास्तव में पाठ बदलने के लिए कार्य करते हैं, लेकिन समारोह ऐसा नाम है जो वास्तव में आवश्यक नहीं है के बावजूद कर सकते हैं:

"1 a,2 b,3 c,4 d".replace(/\d (\w)/g, function(complete_match, matched_letter) { 
    console.log(matched_letter); 
}); 

इस कंसोल में प्रवेश करेंगे a, b, c, तो d। (यह भी "undefined,undefined,undefined,undefined" वापस जाने के लिए नहीं होगा, लेकिन हम यहाँ उस के बारे में परवाह नहीं है।)

आम तौर पर, समारोह तर्क is called with the following parameters को बदलने के लिए:

function(match, p1, p2, [...], offset, string) 
  • match मिलान सबस्ट्रिंग है।
  • p1 आदि मैच के कब्जे वाले समूह हैं, यदि कोई हो। समूह उद्घाटन कोष्ठक के क्रम में हैं जो वे मेल खाते हैं (यानी सबसे पहले, पहले पहले)। यदि समूह एकाधिक सबस्ट्रिंग से मेल खाता है (यानी (.)+ परिदृश्य में), केवल अंतिम (दाएं) सबस्ट्रिंग कैप्चर की जाती है।
  • offset इस मैच
  • string के मूल स्ट्रिंग में सूचकांक स्ट्रिंग जिस पर replace बुलाया गया था है।

मैन्युअल पुनरावृत्ति संभवतः अधिक कुशल है, लेकिन यह विधि धीमी नहीं है और यह छोटा और (IMHO) पढ़ने में आसान है; मैं मैनुअल लूप पर इस पैटर्न का उपयोग करता हूं।

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