2011-10-03 17 views
6

मुझे लगता है कि यह एक मूर्खतापूर्ण गलती होगी लेकिन मेरे लिए, निम्नलिखित केवल "एम" युक्त एक सरणी देता है। इसे देखें:रूबी रेगेक्स, केवल एक कैप्चर (बहुत सरल!)

/(.)+?/.match("Many many characters!").captures 
=> ["M"] 

यह प्रत्येक चरित्र की सरणी क्यों नहीं लौटाता है? मुझे कुछ स्पष्ट रूप से स्पष्ट होना चाहिए क्योंकि मैं नहीं देख सकता कि इसमें क्या गलत है?

संपादित करें: बस एहसास हुआ, मुझे + की आवश्यकता नहीं है? लेकिन यह अभी भी इसके बिना काम नहीं करता है।

संपादित करें: क्षमा करें! मैं स्पष्टीकरण दूंगा: मेरा लक्ष्य उपयोगकर्ताओं को एक नियमित अभिव्यक्ति और स्टाइल और एक इनपुट टेक्स्ट फ़ाइल दर्ज करने की इजाजत देना है, जहां भी कोई मिलान है, टेक्स्ट एचटीएमएल तत्व से घिरा होगा और स्टाइल लागू किया जाएगा, मैं सिर्फ विभाजन नहीं कर रहा हूं पात्रों में स्ट्रिंग, मैंने केवल दिए गए रेगेक्स का उपयोग किया क्योंकि यह सबसे आसान था हालांकि यह मेरे हिस्से पर बेवकूफ था। मैं स्कैन() से कैप्चर समूह कैसे प्राप्त करूं या यह संभव नहीं है? मुझे लगता है कि $ 1 में "!" है (अंतिम मैच?) और कोई अन्य नहीं।

संपादित करें: भगवान, यह वास्तव में मेरा दिन नहीं है। जैसे इंजेक्ट ने मुझे सूचित किया है, कैप्चर अलग-अलग सरणी में संग्रहित होते हैं। मैं मूल स्ट्रिंग से इन कैप्चर का ऑफ़सेट कैसे प्राप्त करूं? मैं एक कैप्चर ऑफसेट प्राप्त करने में सक्षम होना चाहता हूं और फिर इसे दूसरी स्ट्रिंग से घिराऊंगा। या यह है कि जीएसबी क्या है? (मैंने सोचा कि केवल मैच, एक पर कब्जा समूह नहीं बदला गया)

उम्मीद है कि अंतिम संपादन: ठीक है, मुझे बस फिर यह शुरू करते हैं: पी

तो, मैं एक स्ट्रिंग है। उपयोगकर्ता नियमित अभिव्यक्ति दर्ज करने के लिए कॉन्फ़िगरेशन फ़ाइल का उपयोग करेगा, फिर प्रत्येक कैप्चर समूह से जुड़ी शैली। मुझे पूरी स्ट्रिंग को स्कैन करने और प्रत्येक समूह मैच के स्टार्ट और फिनिश या ऑफ़सेट और आकार प्राप्त करने में सक्षम होना चाहिए।

तो अगर एक उपयोगकर्ता को कॉन्फ़िगर किया था ([\w-\.]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4}) (ईमेल पते) तो मैं प्राप्त करने के लिए सक्षम होना चाहिए:

[ ["elliotpotts", 0, 11], 
    ["sample.",  12, 7], 
    ["com",   19, 3] ] 
स्ट्रिंग से

: "[email protected]"

अगर ऐसा नहीं है स्पष्ट है, मेरे साथ कुछ गलत है: पी। बहुत बहुत धन्यवाद दोस्तों, और इतने मरीज होने के लिए धन्यवाद!

+0

मैंने आपके संपादन को देखा, स्कैन से समूह को अलग-अलग सरणी में संग्रहीत किया जाता है, बस अपने regexp और एक परीक्षण स्ट्रिंग को देखें जो आप देखेंगे। उत्तर अभी भी आपके शामिल संपादन –

+0

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

+0

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

उत्तर

9

क्योंकि आपके कब्जा केवल एक एकल वर्ण से मेल खाते है।

"Many many characters!".scan(/./) 
#=> ["M", "a", "n", "y", " ", "m", "a", "n", "y", " ", "c", "h", "a", "r", "a", "c", "t", "e", "r", "s", "!"] 

नोट: (.)+(.+)

>> /(.)+?/.match("Many many characters!").captures 
=> ["M"] 
>> /(.+)?/.match("Many many characters!").captures 
=> ["Many many characters!"] 
>> /(.+?)/.match("Many many characters!").captures 
=> ["M"] 

के रूप में ही आप मैच के लिए हर चरित्र रिकर्सिवली String#scan या String#split उपयोग करें यदि आप कैप्चर समूहों

के बारे में परवाह नहीं है का उपयोग करते हुए स्कैन चाहते हैं नहीं है कि अन्य उत्तर (.) का उपयोग कर रहे हैं, जबकि यह ठीक है अगर आप कैप्चर समूह की परवाह करते हैं, तो यह थोड़ा सा व्यर्थ है यदि आप नहीं करते हैं, अन्यथा यह प्रत्येक चरित्र को इसके ओवे में वापस कर देगा n अलग सरणी, इस तरह:

[["M"], ["a"], ["n"], ["y"], [" "], ["m"], ["a"], ["n"], ["y"], [" "], ["c"], ["h"], ["a"], ["r"], ["a"], ["c"], ["t"], ["e"], ["r"], ["s"], ["!"]] 

अन्यथा, बस split का उपयोग करें: "Many many characters!".split(' ')"

संपादित जवाब में अपने संपादित करने के लिए:

reg = /([\w-\.]+)@((?:[\w]+\.)+)([a-zA-Z]{2,4})/ 
str = "[email protected]" 
str.scan(reg).flatten.map { |capture| [capture, str.index(capture), capture.size] } 
#=> [["elliotpotts", 0, 11], ["sample.", 12, 7], ["com", 19, 3]]` 

ओह, और आप स्कैन की जरूरत नहीं है , आप वास्तव में स्कैनिंग नहीं कर रहे हैं, इसलिए आपको कम से कम उदाहरण के साथ ट्रैवर्स की आवश्यकता नहीं है:

str.match(reg).captures.map { |capture| [capture, str.index(capture), capture.size] } 

भी काम करेगा

+0

धन्यवाद! मुझे एक वैकल्पिक उत्तर भी मिला है और अब इसे पोस्ट कर देगा। धन्यवाद! – Ell

+0

दिए गए दो कोड स्निपेट सामान्य मामले में ऑफ़सेट के लिए सही ढंग से काम नहीं करते हैं, वे केवल तभी काम करते हैं जब मिलान किए गए सबस्ट्रिंग सभी अलग हैं। यदि, उदाहरण के लिए, "एच" के लिए 3 मैचों हैं तो एक ही इंडेक्स ('एच' का पहला उदाहरण) 3 बार वापस कर दिया जाता है। str.index (कैप्चर) कैप्चर किए गए सबस्ट्रिंग के पहले उदाहरण की अनुक्रमणिका देता है। – jpwynn

0

यह केवल एक चरित्र लौट रहा है क्योंकि आपने इसे मिलान करने के लिए कहा है। आप शायद बजाय scan उपयोग करना चाहते हैं:

str = "Many many characters!" 
matches = str.scan(/(.)/) 
1

हाँ, कुछ महत्वपूर्ण याद किया गया था ;-)

(...) केवल परिचय एक कैप्चर समूह: बार ग्रुप मैच की संख्या अप्रासंगिक है के रूप में सूचकांक नियमित द्वारा केवल निर्धारित किया जाता है स्वयं अभिव्यक्ति और इनपुट नहीं।

कुंजी एक "वैश्विक नियमित अभिव्यक्ति" है, जो क्रमशः नियमित अभिव्यक्ति को कई बार लागू करेगी। रूबी में इस Regex#match से String#scan को inverting साथ किया जाता है (कई अन्य भाषाओं के लिए एक "/ जी" रेगुलर एक्सप्रेशन संशोधक है):

"Many many chara­cters!".sc­an(/(.)+?/­) 
# but more simply (or see answers using String#split) 
"Many many chara­cters!".sc­an(/(.)/­) 

मुबारक कोडिंग

0

निम्नलिखित कोड Get index of string scan results in ruby से है और मेरी पसंद के लिए संशोधित ।

[].tap {|results| 
    "abab".scan(/a/) {|capture| 
     results.push(([capture, Regexp::last_match.offset(0)]).flatten) 
    } 
} 

=> [["a", 0], ["a", 2]] 
संबंधित मुद्दे