रेगेक्स और बैकरेफरेंस के साथ रूबी स्विच स्टेटमेंट (केस ... कब) लिखें?


86

मुझे पता है कि मैं नियमित अभिव्यक्ति के खिलाफ मैच की जांच के लिए रूबी केस स्टेटमेंट लिख सकता हूं। हालाँकि, मैं अपने रिटर्न स्टेटमेंट में मैच डेटा का उपयोग करना चाहूंगा। कुछ इस तरह से अर्ध-स्यूडोकोड:

foo = "10/10/2011"

case foo
    when /^([0-9][0-9])/
        print "the month is #{match[1]}"
    else
        print "something else"
end

मैं उसे कैसे प्राप्त कर सकता हूं?

धन्यवाद!


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


1
रूबी का Date.parse कई तारीख स्वरूपों को समझता है। या तुमने कोशिश की?
Raine

यद्यपि यह इस प्रश्न का उत्तर नहीं देता है, आप क्रोनिक मणि को देखना चाहते हैं ...
DGM

जवाबों:


153

नवीनतम रेगुलर एक्सप्रेशन मिलान समूहों के लिए संदर्भ हमेशा में जमा हो जाती छद्म चर $1 करने के लिए $9:

case foo
when /^([0-9][0-9])/
    print "the month is #{$1}"
else
    print "something else"
end

आप $LAST_MATCH_INFOसंपूर्ण MatchDataऑब्जेक्ट पर प्राप्त करने के लिए छद्म चर का उपयोग भी कर सकते हैं । यह नामांकित कैप्चर का उपयोग करते समय उपयोगी हो सकता है:

case foo
when /^(?<number>[0-9][0-9])/
    print "the month is #{$LAST_MATCH_INFO['number']}"
else
    print "something else"
end

1
@Yossi क्या आपके पास थ्रेड सुरक्षा के बारे में आपकी टिप्पणी का स्रोत है? मैंने सिर्फ माणिक 1.8.7 में एक प्रयोग किया था जो यह दर्शाता है कि यह धागा-सुरक्षित है! (धागा एक रेगेक्स से मेल खाता है हर एक सेकंड - irb में जाँच अगर स्थानीय मैच बंद हो रहे हैं)
जोएल

5
नियमित भाव के साथ करने के लिए -1 $ चर वैश्विक नहीं हैं, भले ही इसके सामने एक डॉलर का चिह्न हो।
एंड्रयू ग्रिम

@AndrewGrimm इसे इंगित करने के लिए धन्यवाद। मुझे इसकी जानकारी नहीं थी। मुझे बहुत सारे पुराने कोड बदलने होंगे: - /
Yossi

आप यह भी कर सकते हैं $1, $2... $9या Regexp.last_match(1)के रूप में rubocop द्वारा सिफारिश
एडगर ओर्टेगा

6

यहां एक वैकल्पिक दृष्टिकोण है जो आपको समान परिणाम देता है लेकिन स्विच का उपयोग नहीं करता है। यदि आप अपनी नियमित अभिव्यक्तियों को एक सरणी में रखते हैं, तो आप कुछ ऐसा कर सकते हैं:

res = [ /pat1/, /pat2/, ... ]
m   = nil
res.find { |re| m = foo.match(re) }
# Do what you will with `m` now.

mब्लॉक के बाहर घोषणा करने से यह ब्लॉक के findसाथ किए जाने के बाद भी उपलब्ध होने की अनुमति देता है और findजैसे ही ब्लॉक एक वास्तविक मूल्य लौटाता है, तो आपको वही शॉर्टकट व्यवहार मिलता है जो एक स्विच आपको देता है। MatchDataयदि आपको इसकी आवश्यकता है तो यह आपको पूर्ण देता है (शायद आप अपने रेगेक्स में नामित कैप्चर समूहों का उपयोग करना चाहते हैं) और अच्छी तरह से अपने खोज तर्क (जो कि स्पष्ट कोड प्राप्त नहीं कर सकते हैं) से आपके रेगीक्स को अलग करता है, आप एक से भी अपने रेगीक्स लोड कर सकते हैं कॉन्फ़िगर फ़ाइल या चुनें कि उनमें से कौन सा सेट आप रन टाइम में चाहते थे।


मैं caseदृष्टिकोण का उपयोग करके थ्रेड सुरक्षा के बारे में भी सोच रहा था । हो सकता है कि आप मामले के दृष्टिकोण (?) के साथ एक वैश्विक चर के बजाय एक थ्रेडेड परिदृश्य में म्यू के दृष्टिकोण का उपयोग करना चाहते हैं
कैस्पर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.