2010-10-09 28 views
5

मैं जावास्क्रिप्ट में लागू एक स्ट्रिंग के भीतर सबसे लंबी दोहराव वाली स्ट्रिंग और नियमित अभिव्यक्ति आधारित दृष्टिकोण का उपयोग करना चाहता हूं।नियमित अभिव्यक्तियों का उपयोग करके जावास्क्रिप्ट में सबसे लंबे समय तक दोहराने वाले सबस्ट्रिंग का पता लगाएं

मेरे पास एक PHP कार्यान्वयन है, जो सीधे जावास्क्रिप्ट पर पोर्ट किया जाता है, काम नहीं करता है।

पीएचपी कार्यान्वयन सवाल "Find longest repeating strings?" के जवाब से लिया जाता है:

preg_match_all('/(?=((.+)(?:.*?\2)+))/s', $input, $matches, PREG_SET_ORDER); 

यह $matches[0][X] से स्थापित हो जाएगा सबसे लंबे समय तक दोहराए जाने-स्ट्रिंग के साथ $input में पाया जा सकता है (जहां X$matches[0] की लंबाई है)। मैंने कई इनपुट तारों के साथ इसका परीक्षण किया है और मुझे विश्वास है कि आउटपुट सही है।

जावास्क्रिप्ट में निकटतम प्रत्यक्ष बंदरगाह है:

var matches = /(?=((.+)(?:.*?\2)+))/.exec(input); 

यह सही परिणाम

 
input     Excepted result matches[0][X] 
====================================================== 
inputinput    input    input 
7inputinput   input    input 
inputinput7   input    input 
7inputinput7   input    7 
XXinputinputYY   input    XX 

मैं नियमित अभिव्यक्ति के साथ पर्याप्त परिचित नहीं कर रहा हूँ समझने के लिए नियमित अभिव्यक्ति यहां इस्तेमाल नहीं देता कर रहा है।

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

क्या उपरोक्त नियमित अभिव्यक्ति को संशोधित किया जा सकता है कि अपेक्षित आउटपुट जावास्क्रिप्ट में वापस आ गया है? मैं स्वीकार करता हूं कि यह एक लाइनर में संभव नहीं हो सकता है।

उत्तर

5

जावास्क्रिप्ट मैच केवल पहला मैच लौटाता है - आपको कई परिणामों को खोजने के लिए लूप करना होगा।

function maxRepeat(input) { 
var reg = /(?=((.+)(?:.*?\2)+))/g; 
var sub = ""; //somewhere to stick temp results 
var maxstr = ""; // our maximum length repeated string 
reg.lastIndex = 0; // because reg previously existed, we may need to reset this 
sub = reg.exec(input); // find the first repeated string 
while (!(sub == null)){ 
    if ((!(sub == null)) && (sub[2].length > maxstr.length)){ 
    maxstr = sub[2]; 
    } 
    sub = reg.exec(input); 
    reg.lastIndex++; // start searching from the next position 
} 
return maxstr; 
} 

// I'm logging to console for convenience 
console.log(maxRepeat("aabcd"));    //aa 
console.log(maxRepeat("inputinput"));  //input 
console.log(maxRepeat("7inputinput"));  //input 
console.log(maxRepeat("inputinput7"));  //input 
console.log(maxRepeat("7inputinput7"));  //input 
console.log(maxRepeat("xxabcdyy"));   //x 
console.log(maxRepeat("XXinputinputYY")); //input 

ध्यान दें कि "xxabcdyy" के लिए आप केवल "x" मिलता है वापस, के रूप में यह अधिकतम लंबाई की पहली स्ट्रिंग रिटर्न: एक छोटी सी परीक्षण इस अपेक्षित परिणाम हो जाता है पता चलता है।

0

ऐसा लगता है कि जेएस रेगेक्स थोड़ा अजीब हैं। मेरे पास पूरा जवाब नहीं है, लेकिन मुझे यह मिला है।

हालांकि मैंने सोचा कि उन्होंने वही काम re.exec() और "string" किया है। मैच (पुनः) अलग-अलग व्यवहार करते हैं। एक्सेक केवल पहले मैच को वापस लौटता प्रतीत होता है, जबकि मैच उन सभी को वापस करने लगता है (दोनों मामलों में/जी का उपयोग करके)।

दूसरी तरफ, निष्पादन सही ढंग से काम करता है? = रेगेक्स में जबकि मैच सभी खाली तार देता है। निकाला जा रहा है? = हमें

re = /((.+)(?:.*?\2)+)/g 

का उपयोग के साथ छोड़ देता है कि

"XXinputinputYY".match(re); 

रिटर्न

["XX", "inputinput", "YY"] 

जबकि

re.exec("XXinputinputYY"); 

रिटर्न

["XX", "XX", "X"] 

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

एक और बात, मैंने फायरबग के कंसोल में परीक्षण किया जिसने $ 1 का समर्थन नहीं करने के बारे में एक त्रुटि फेंक दी, तो हो सकता है कि $ vars देखने में लायक कुछ हो।

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

  • कोई संबंधित समस्या नहीं^_^