रूबी में स्ट्रिंग से संख्या निकालें


82

मैं इस कोड का उपयोग कर रहा हूं:

s = line.match( /ABCD(\d{4})/ ).values_at( 1 )[0] 

तार से संख्या निकालने के लिए जैसे:

ABCD1234
ABCD1235
ABCD1236

आदि।

यह काम करता है, लेकिन मुझे आश्चर्य है कि रूबी में मेरे पास इसके अलावा और क्या विकल्प है?

मेरा कोड:

ids = [] 
someBigString.lines.each {|line|
   ids << line.match( /ABCD(\d{4})/ ).values_at( 1 )[0] 
}

जवाबों:


38
a.map {|x| x[/\d+/]}

मुझे क्या mapसमझना चाहिए इसका अर्थ क्या है? मैं समझता हूं collectलेकिन मुझे मानचित्र को समझने में हमेशा परेशानी हुई है।
ऑस्कररिज़

3
@ ऑस्कर रेयेस, एनुमेरबल # मैप एन्युमेरेबल # कलेक्ट का एक पर्याय है
वेन कॉनराड

3
FYI करें: यदि आपके पास अन्य वर्णों द्वारा विभाजित संख्याएँ हैं, तो यह केवल संख्याओं के पहले "चंक" को पकड़ता है। तो '123ABC456' के लिए, यह केवल '123' को ही लेगा। यदि आप सभी संख्याएँ प्राप्त करना चाहते हैं, तो line.gsub (/ [^ 0-9] /, '') जैसी किसी चीज़ का उपयोग करें।
जोशुआ पिंटर

4
यह भी स्पष्ट करना चाहिए कि यह एक एरेमेबल पर काम करता है जैसे कि एक सरणी, न कि एक स्ट्रिंग जैसा कि शीर्षक पूछ रहा है
एलन

4
NoMethodError: अपरिभाषित विधि स्ट्रिंग के लिए `नक्शा '
गैरी गोमेज़

177

Http://www.ruby-forum.com/topic/125709 के अनुसार कई रूबी तरीके हैं

  1. line.scan(/\d/).join('')
  2. line.gsub(/[^0-9]/, '')
  3. line.gsub(/[^\d]/, '')
  4. line.tr("^0-9", '')
  5. line.delete("^0-9")
  6. line.split(/[^\d]/).join
  7. line.gsub(/\D/, '')

आप सांत्वना पर प्रत्येक की कोशिश करो।

उस पोस्ट में बेंचमार्क रिपोर्ट भी देखें।


24
लाइन.डेलीट ("^ 0-9") लिंक के अनुसार सबसे तेज़ है
वेस्टन गैंगर

62

और भी सरल उपाय है

line.scan(/\d+/).first

यह केवल स्ट्रिंग से लगातार संख्याओं का पहला मैच लौटाता है। तो 'ab123cd45'.scan(/\d+/).firstबस लौटेगा12
Lacostenycoder

5

सबसे सरल और तेज़ तरीका है कि सभी पूर्णांक स्ट्रिंग से बाहर निकले।

str = 'abc123def456'

str.delete("^0-9")
=> "123456"

यहाँ उपलब्ध कराए गए कुछ अन्य समाधानों के साथ एक लंबे स्ट्रिंग पर बेंचमार्क की तुलना करते हुए, हम यह देख सकते हैं कि यह तीव्रता का क्रम है:

require 'benchmark'

@string = [*'a'..'z'].concat([*1..10_000].map(&:to_s)).shuffle.join

Benchmark.bm(10) do |x|
  x.report(:each_char) do
    @string.each_char{ |c| @string.delete!(c) if c.ord<48 or c.ord>57 }
  end
  x.report(:match) do |x|
    /\d+/.match(@string).to_s
  end
  x.report(:map) do |x|
    @string.split.map {|x| x[/\d+/]}
  end
  x.report(:gsub) do |x|
    @string.gsub(/\D/, '')
  end
  x.report(:delete) do
    @string.delete("^0-9")
  end
end

             user     system      total        real
each_char    0.020000   0.020000   0.040000 (  0.037325)
match        0.000000   0.000000   0.000000 (  0.001379)
map          0.000000   0.000000   0.000000 (  0.001414)
gsub         0.000000   0.000000   0.000000 (  0.000582)
delete       0.000000   0.000000   0.000000 (  0.000060)

4
your_input = "abc1cd2"
your_input.split(//).map {|x| x[/\d+/]}.compact.join("").to_i

यह काम करना चाहिए।


कृपया अपने कोड को संपादित करने पर विचार करें कि आपका कोड क्या करता है और यह समस्या का समाधान क्यों करेगा, इसके बारे में अधिक विवरण जोड़ने के लिए। एक जवाब जो ज्यादातर सिर्फ कोड होता है (भले ही यह काम कर रहा हो) आमतौर पर ओपी को उनकी समस्या को समझने में मदद नहीं करेगा।
सुपरबाइस्डमैन

2

एक और समाधान लिखने के लिए हो सकता है:

myString = "sami103"
myString.each_char{ |c| myString.delete!(c) if c.ord<48 or c.ord>57 } #In this case, we are deleting all characters that do not represent numbers.

अब आप टाइप करें तो

myNumber = myString.to_i #or myString.to_f

इसे वापस करना चाहिए


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

0

स्ट्रिंग से संख्या भाग निकालने के लिए निम्नलिखित का उपयोग करें:

str = 'abcd1234'
/\d+/.match(str).try(:[], 0)

इसे वापस लौटना चाहिए 1234


आप की जरूरत नहीं है matchया tryअगर आप इस स्ट्रिंग मिलान वाक्यविन्यास का उपयोग करते हैंstr[/\d+/]
Lacostenycoder

यह भी .tryमुख्य रूबी नहीं है, इसलिए यह उत्तर बिना active_support/core_ext/object/try.rbया पटरियों के विफल हो जाता है
लैकोस्टेनकोडर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.