2011-05-14 12 views
16

क्या कोई यह बता सकता है कि मैं रूबी में नियमित अभिव्यक्तियों का उपयोग कैसे कर सकता हूं ताकि केवल स्ट्रिंग के मैचों को वापस कर सकें।नियमित अभिव्यक्ति से मेल खाने वाली टेक्स्ट फ़ाइल में रेखाएं ढूंढना

उदाहरण के लिए, कोड उस में नामों की एक श्रृंखला के साथ एक .txt फ़ाइल में पढ़ता है यदि:

John Smith 
James Jones 
David Brown 
Tom Davidson 
etc etc 

..और शब्द मिलान करने के लिए किया जा रहा है के रूप में में लिखा गया 'ohn', यह तो होगा बस 'जॉन स्मिथ' वापस लौटें, लेकिन अन्य नामों में से कोई भी नहीं।

उत्तर

14

हो सकता है कि मैं इस समस्या को पूरी तरह से समझ नहीं हूँ, लेकिन आप कुछ की तरह कर सकता है:

File.readlines("path/to/file.txt").select { |line| line =~ /ohn/ } 

सभी लाइनों है कि आपके मानदंड से मेल खाते की एक सरणी प्राप्त करने के लिए।

9
query = 'ohn' 
names = File.readlines('names.txt') 
matches = names.select { |name| name[/#{query}/i] } 
#=> ["John Smith"] 

regex के अंत में i निकालें आप क्वेरी केस संवेदी होने के लिए चाहते हैं।

+0

एकदम सही है कि की एक सूची खोज करने के लिए इस्तेमाल किया जा सकता आप तरह सर धन्यवाद! स्मृति को ध्यान में रखने के लिए – Jbod

21

यहां जा रहे हैं कि आप कहां जा रहे हैं इसके कुछ अलग तरीके हैं।

पहले नोटिस मैं फ़ाइल से लाइनों को पढ़ने के लिए कोड लिखने का एक और बेवकूफ तरीका उपयोग कर रहा हूं। रुबी के आईओ और फाइल लाइब्रेरीज़ एक अच्छी साफ पैकेज में फ़ाइल को खोलने, पढ़ने और बंद करने में बहुत आसान बनाते हैं।

File.each_line('file.txt') do |li| 
    puts li if (li['ohn']) 
end 

यह लाइन में कहीं भी 'ओह' की तलाश में है, लेकिन नियमित अभिव्यक्ति से परेशान नहीं है।

File.each_line('file.txt') do |li| 
    puts li if (li[/ohn/]) 
end 

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

File.each_line('file.txt') do |li| 
    puts li if (li[/ohn\b/]) 
end 

यह 'ओह' के साथ समाप्त होने वाले नामों की तलाश करने का एक आसान तरीका है। यह रेगेक्स का उपयोग करता है लेकिन यह भी निर्दिष्ट करता है कि एक शब्द के अंत में पैटर्न होना चाहिए। \b का अर्थ है "शब्द-सीमा"।

साथ ही, फ़ाइलों को पढ़ने के दौरान, हमेशा यह सोचना महत्वपूर्ण है कि फ़ाइल पढ़ने के बाद आपके ऐप पर उपलब्ध रैम से अधिक हो सकता है या नहीं। एक फ़ाइल में एक पूरी फ़ाइल को स्मृति में पढ़ना आसान है, फिर इसे रैम से संसाधित करें, लेकिन यदि आप भौतिक RAM को उपलब्ध करते हैं तो आप अपने ऐप या मशीन को अपंग या मार सकते हैं।


आप जानते हैं कि अन्य उत्तर द्वारा दिखाए गए कोड रैम में पूरे फ़ाइल लोड वास्तव में या किसी भी तरह readlines समारोह से चयन कार्य करने के लिए स्ट्रीमिंग द्वारा अनुकूलित है है?

IO#readlines प्रलेखन से:

पूरे व्यक्ति लाइनों के रूप में नाम से निर्दिष्ट फ़ाइल पढ़ता है, और एक सरणी में उन पंक्तियों देता है। रेखाएं सीपी से अलग होती हैं।

एक अतिरिक्त विचार एक बड़े, थोक पढ़ने के दौरान स्मृति आवंटन है।यहां तक ​​कि यदि आपके पास पर्याप्त रैम है, तो आप उन स्थितियों में भाग ले सकते हैं जहां डेटा में डेटा पढ़ता है, यह पता चलता है कि यह चर के लिए पर्याप्त स्मृति आवंटित नहीं किया गया है, और इसे रोकना है क्योंकि यह अधिक पकड़ लेता है। वह चक्र तब तक दोहराता है जब तक कि पूरी फ़ाइल लोड न हो जाए।

मैं कई सालों पहले इस बात से संवेदनशील हो गया था कि जब मैं एचपी के सबसे बड़े मिनी पर एक पर्ल ऐप में एक बहुत बड़ी डेटा फ़ाइल लोड कर रहा था, तो मैंने प्रबंधित किया। ऐप समय-समय पर कुछ सेकंड के लिए रुक जाएगा और मुझे पता नहीं लगा कि क्यों। मैं डीबगर में गिरा दिया और समस्या नहीं मिल सका। अंत में, पुराने स्कूल प्रिंट स्टेटमेंट का उपयोग करके रन का पता लगाने के द्वारा मैंने विराम को एक फ़ाइल "स्लर्प" में अलग कर दिया। मेरे पास बहुत सी रैम थी, और प्रसंस्करण शक्ति के बहुत सारे थे, लेकिन पर्ल पर्याप्त स्मृति आवंटित नहीं कर रहा था। मैंने रेखा से लाइन पढ़ने के लिए स्विच किया और ऐप इसकी प्रसंस्करण के माध्यम से उड़ गया। रूल की तरह रूबी के पास अच्छा I/O है, और जब यह लाइन-दर-रेखा पढ़ रहा है तो बहुत बड़ी फ़ाइल पढ़ सकता है। मुझे टेक्स्ट फ़ाइल को स्लिपिंग करने का कोई अच्छा कारण कभी नहीं मिला है, सिवाय इसके कि जब सामग्री हो, तो मैं कई लाइनों में फैलाना चाहता हूं, लेकिन यह एक आम घटना नहीं है।

+1

+1। क्या आपको पता है कि अन्य उत्तरों द्वारा दिखाया गया कोड वास्तव में पूरी फ़ाइल को रैम में लोड कर रहा है या किसी भी तरह से 'रीडलाइन' फ़ंक्शन से 'चयन' फ़ंक्शन पर स्ट्रीम करके अनुकूलित किया गया है? पूरी फ़ाइल को स्मृति में पढ़ने के लिए –

+0

+1। –

+1

@ जेसनएम, 'रीडलाइन' का उपयोग करने का सुझाव देने वाला कोई भी जवाब पूरी फ़ाइल को स्मृति में लोड कर रहा है। यह एक सरणी के रूप में है, लेकिन यह स्मृति में है। –

1

पुराना सवाल है, लेकिन Array#grep भी तार

File.readlines("names.txt").grep /#{query}/i 
संबंधित मुद्दे

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