क्या रूबी में एक नियमित अभिव्यक्ति के हर मैच को खोजने का एक त्वरित तरीका है? मैंने रूबी एसटीएल में रेगेक्स ऑब्जेक्ट के माध्यम से देखा है और कोई फायदा नहीं हुआ।
क्या रूबी में एक नियमित अभिव्यक्ति के हर मैच को खोजने का एक त्वरित तरीका है? मैंने रूबी एसटीएल में रेगेक्स ऑब्जेक्ट के माध्यम से देखा है और कोई फायदा नहीं हुआ।
जवाबों:
का उपयोग करना scan
चाहिए चाल:
string.scan(/regex/)
/(?=(...))/
।
सभी मिलान स्ट्रिंग्स को खोजने के लिए, स्ट्रिंग की scan
विधि का उपयोग करें।
str = "A 54mpl3 string w1th 7 numb3rs scatter36 ar0und"
str.scan(/\d+/)
#=> ["54", "3", "1", "7", "3", "36", "0"]
यदि आप चाहते हैं, MatchData
जो Regexp match
विधि द्वारा लौटाए गए ऑब्जेक्ट का प्रकार है , तो उपयोग करें:
str.to_enum(:scan, /\d+/).map { Regexp.last_match }
#=> [#<MatchData "54">, #<MatchData "3">, #<MatchData "1">, #<MatchData "7">, #<MatchData "3">, #<MatchData "36">, #<MatchData "0">]
उपयोग करने MatchData
का लाभ यह है कि आप निम्न विधियों का उपयोग कर सकते हैं offset
:
match_datas = str.to_enum(:scan, /\d+/).map { Regexp.last_match }
match_datas[0].offset(0)
#=> [2, 4]
match_datas[1].offset(0)
#=> [7, 8]
यदि आप अधिक जानना चाहते हैं तो इन प्रश्नों को देखें:
विशेष चरों के बारे में पढ़ना $&
, $'
, $1
, $2
रूबी में सहायक भी हो जाएगा।
यदि आपके पास समूहों के साथ regexp है:
str="A 54mpl3 string w1th 7 numbers scatter3r ar0und"
re=/(\d+)[m-t]/
आप scan
मिलान समूहों को खोजने के लिए स्ट्रिंग की विधि का उपयोग कर सकते हैं :
str.scan re
#> [["54"], ["1"], ["3"]]
मिलान पैटर्न खोजने के लिए:
str.to_enum(:scan,re).map {$&}
#> ["54m", "1t", "3r"]
str.scan(/\d+[m-t]/) # => ["54m", "1t", "3r"]
की तुलना में अधिक मुहावरेदार हैstr.to_enum(:scan,re).map {$&}
/(\d+)[m-t]/
नहीं /\d+[m-t]/
: re = /(\d+)[m-t]/; str.scan(re)
एक ही है str.scan(/(\d+)[mt]/)
लेकिन मुझे #> मिलता है [["" 54 "], [" 1 "], [" 3 "]]
और "54m", "1t", "3r"]
यह सवाल नहीं था: यदि मेरे पास एक समूह के साथ एक नियमित अभिव्यक्ति है और सभी पैटर्न को नियमित रूप से बदलने के बिना कब्जा करना चाहते हैं। अभिव्यक्ति (समूह को छोड़कर), मैं इसे कैसे कर सकता हूं? इस अर्थ में, एक संभावित समाधान, भले ही थोड़ा गूढ़ और पढ़ने में मुश्किल हो,:str.to_enum(:scan,re).map {$&}
आप उपयोग कर सकते हैं string.scan(your_regex).flatten
। यदि आपके रेगेक्स में समूह हैं, तो यह एक सादे मैदान में वापस आएगा।
string = "A 54mpl3 string w1th 7 numbers scatter3r ar0und"
your_regex = /(\d+)[m-t]/
string.scan(your_regex).flatten
=> ["54", "1", "3"]
रेगेक्स एक नामित समूह भी हो सकता है।
string = 'group_photo.jpg'
regex = /\A(?<name>.*)\.(?<ext>.*)\z/
string.scan(regex).flatten
gsub
यदि आप मैचडाटा चाहते हैं तो आप इसका उपयोग कर सकते हैं ।
str.gsub(/\d/).map{ Regexp.last_match }
your_regex = /(\d+)[m-t]/
और आपको उपयोग करने की आवश्यकता नहीं होगी flatten
। आपका अंतिम उदाहरण उपयोग करता है last_match
जो इस मामले में शायद सुरक्षित है, लेकिन एक वैश्विक है और संभवतः किसी भी regex को कॉल करने से पहले मिलान किए जाने पर अधिलेखित किया जा सकता है last_match
। इसके बजाय शायद इसका उपयोग करना सुरक्षित है string.match(regex).captures # => ["group_photo", "jpg"]
या string.scan(/\d+/) # => ["54", "3", "1", "7", "3", "0"]
जैसा कि अन्य उत्तरों में दिखाया गया है, पैटर्न और जरूरतों के आधार पर।