2009-12-31 33 views
12

जब मैं की तरह एक नियमित अभिव्यक्ति लिखें:जावास्क्रिप्ट नियमित अभिव्यक्तियों में समूहों के सूचकांक कैसे खोजें?

var m = /(s+).*?(l)[^l]*?(o+)/.exec("this is hello to you"); 
console.log(m); 

मैं युक्त एक मैच वस्तु पाने के निम्नलिखित:

{ 
    0: "s is hello", 
    1: "s", 
    2: "l", 
    3: "o", 
    index: 3, 
    input: "this is hello to you" 
} 

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

क्या मिलान किए गए समूह का ऑफसेट पाने का कोई तरीका है?

+0

संभावित डुप्लिकेट [जावास्क्रिप्ट regex में प्रत्येक कैप्चर की अनुक्रमणिका प्राप्त करें] (http://stackoverflow.com/questions/15934353/get-index-of-each-capture-in-a-javascript-regex) – Vanuan

उत्तर

13

आप सीधे एक मैच समूह की अनुक्रमणिका प्राप्त नहीं कर सकते हैं।

var m= /(s+)(.*?)(l)([^l]*?)(o+)/.exec('this is hello to you'); 

अब आप भागों में पूरे मैच मिल गया है:: क्या आप क्या करना है पहले भी हैं जिन्हें आप परवाह नहीं है एक मैच समूह में हर चरित्र डाल दिया, के बारे में है

['s is hello', 's', ' is hel', 'l', '', 'o'] 

function indexOfGroup(match, n) { 
    var ix= match.index; 
    for (var i= 1; i<n; i++) 
     ix+= match[i].length; 
    return ix; 
} 

console.log(indexOfGroup(m, 3)); // 11 
+0

नाइस उपाय। लेकिन मेरे मामले में मुझे अतिरिक्त माता-पिता को स्वचालित रूप से जोड़ना होगा। और बैकरेन्फर को ठीक करें यदि कोई + मूल समूह संख्या याद रखें। यह स्कोप मिलान के साथ एक वाक्यविन्यास हाइलाइटर के लिए है, और वर्तमान समाधान आधा हाइडलाइटर का उपयोग रेगेक्सपी सिंटैक्स का विश्लेषण करने के लिए करना है + बाद में अमूर्त वाक्यविन्यास पेड़ में सामान के सभी प्रकार कर रहा है। कोड की 300 लाइनों को शामिल करने के बजाय, मुझे एक और आसान समाधान पसंद है। –

+0

इसे ऑरिजिनल रेगेक्सप्स को संशोधित करने की आवश्यकता है – pie6k

8

मैं एक साधारण लिखा था (अच्छी तरह से प्रारंभ थोड़ा फूला हुआ मिल गया) जावास्क्रिप्ट वस्तु हल करने के लिए: समूह सूचकांक करने के लिए मैच सूचकांक से ऑफसेट करने के लिए तो आप अपने समूह से पहले तार की लंबाई को जोड़ सकते हैं इस एक परियोजना पर समस्या जो मैं हाल ही में काम कर रहा हूं। यह स्वीकार्य उत्तर के समान ही काम करता है लेकिन नया regexp उत्पन्न करता है और आपके द्वारा स्वचालित रूप से अनुरोध किए गए डेटा को खींचता है।

var exp = new MultiRegExp(/(firstBit\w+)this text is ignored(optionalBit)?/i); 
var value = exp.exec("firstbitWithMorethis text is ignored"); 

value = {0: {index: 0, text: 'firstbitWithMore'}, 
     1: null}; 

गिट रेपो: My MultiRegExp। उम्मीद है कि इससे वहां किसी को मदद मिलेगी।

संपादित अगस्त, 2015:

मुझे का प्रयास करें: MultiRegExp Live

1

एक और जावास्क्रिप्ट वर्ग जो भी नेस्टेड समूहों को पार्स करने में सक्षम है के तहत उपलब्ध है: https://github.com/valorize/MultiRegExp2

उपयोग:

let regex = /a(?:)bc(def(ghi)xyz)/g; 
let regex2 = new MultiRegExp2(regex); 

let matches = regex2.execForAllGroups('ababa bcdefghixyzXXXX')); 

Will output: 
[ { match: 'defghixyz', start: 8, end: 17 }, 
    { match: 'ghi', start: 11, end: 14 } ] 
+0

अच्छा लगता है, लेकिन मुझे लगता है कि जनरेटर फ़ंक्शन को जोड़ना बेहतर होता है, कुछ स्थितियों में सभी समूहों को कोई आवश्यकता नहीं होती है। – Mithril

+0

@ मिथिल क्या आप https://github.com/valorize/MultiRegExp2/issues/5 में जो सोचते हैं उसका विस्तार कर सकते हैं? – velop

0

ecma regular expression syntax के आधार पर मैं एक पार्सर संबंधित RegExp वर्ग का एक विस्तार लिखा है जो इस समस्या के अलावा हल करता है (पूर्ण अनुक्रमित निष्पादन विधि) साथ ही जावास्क्रिप्ट RegExp कार्यान्वयन की अन्य सीमाएं उदाहरण के लिए: समूह आधारित खोज & प्रतिस्थापित करें। आप test and download the implementation here (एनपीएम मॉड्यूल के रूप में भी उपलब्ध हैं) कर सकते हैं।

कार्यान्वयन काम करता है के रूप में (छोटा सा उदाहरण) इस प्रकार है:

//Retrieve content and position of: opening-, closing tags and body content for: non-nested html-tags. 
var pattern = '(<([^ >]+)[^>]*>)([^<]*)(<\\/\\2>)'; 
var str = '<html><code class="html plain">first</code><div class="content">second</div></html>'; 
var regex = new Regex(pattern, 'g'); 
var result = regex.exec(str); 

console.log(5 === result.length); 
console.log('<code class="html plain">first</code>'=== result[0]); 
console.log('<code class="html plain">'=== result[1]); 
console.log('first'=== result[3]); 
console.log('</code>'=== result[4]); 
console.log(5=== result.index.length); 
console.log(6=== result.index[0]); 
console.log(6=== result.index[1]); 
console.log(31=== result.index[3]); 
console.log(36=== result.index[4]); 

मैं भी @velop से कार्यान्वयन की कोशिश की लेकिन कार्यान्वयन उदाहरण इसे सही ढंग से जैसे backreferences प्रबंधन नहीं करती है के लिए गाड़ी लगता है "/ a (?:) बीसी (डीफ़ (\ 1 गीही) xyz)/g" - सामने में पैराथेसिस जोड़ते समय बैकरेफर \ 1 तदनुसार वृद्धि की आवश्यकता है (जो उसके कार्यान्वयन में मामला नहीं है) ।

+0

कृपया विवरण का उपयोग करें कि आप कैसे काम कर रहे हैं। कभी-कभी अज्ञात रिक्त स्थान से डाउनलोड करना खतरनाक होता है। – Alexan

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