रूबी, एक स्ट्रिंग से अंतिम एन अक्षर हटा दें?


263

nएक स्ट्रिंग से अंतिम वर्णों को हटाने का पसंदीदा तरीका क्या है ?


यदि आप प्रत्यय जानते हैं (शीर्ष उत्तर यह जानने के लिए यहां बहुत आते हैं), तो आप delete_suffixरूबी 2.5 से उपयोग कर सकते हैं । अधिक जानकारी यहाँ
SRack

जवाबों:


36

रूबी 2.5+

रूबी 2.5 के रूप में आप उपयोग कर सकते हैं delete_suffixया delete_suffix!एक तेज और पठनीय तरीके से इस लक्ष्य को हासिल करने के लिए।

विधियों पर डॉक्स यहाँ हैं

यदि आप जानते हैं कि प्रत्यय क्या है, तो यह मुहावरा है (और मैं तर्क दूंगा, यहाँ तक कि अन्य उत्तरों की तुलना में अधिक पठनीय है):

'abc123'.delete_suffix('123')     # => "abc"
'abc123'.delete_suffix!('123')    # => "abc"

यह शीर्ष उत्तर की तुलना में काफी तेज (लगभग 40% बैंग विधि के साथ) है। यहाँ उसी बेंचमार्क का परिणाम है:

                     user     system      total        real
chomp            0.949823   0.001025   0.950848 (  0.951941)
range            1.874237   0.001472   1.875709 (  1.876820)
delete_suffix    0.721699   0.000945   0.722644 (  0.723410)
delete_suffix!   0.650042   0.000714   0.650756 (  0.651332)

मुझे उम्मीद है कि यह उपयोगी है - ध्यान दें कि विधि वर्तमान में एक रेगेक्स को स्वीकार नहीं करती है, यदि आप प्रत्यय नहीं जानते हैं तो यह समय के लिए व्यवहार्य नहीं है। हालाँकि, स्वीकृत उत्तर के रूप में ( अद्यतन: लेखन के समय ) वही तय करता है, मैंने सोचा कि यह कुछ लोगों के लिए उपयोगी हो सकता है।


1
@JPSilvashy मैं एक चेकमार्क को खोने से अधिक प्रसन्न कभी नहीं हुआ। यह एक बेहतरीन जवाब है।
वेन कॉनराड

1
यह एक महान और तेज़ कार्य है, लेकिन यह सही उत्तर नहीं है क्योंकि यह उस प्रश्न का उत्तर नहीं देता है जो वास्तव में हैWhat is the preferred way of removing the last n characters from a string?
सैम

1
फीडबैक @Sam के लिए धन्यवाद - इस सवाल का लगभग नौ साल तक जवाब था कि इसने एक ही काम किया, लिखने के समय 261 के साथ। जेपी ने स्वीकार किया और हाल ही में इस पर स्विच किया, इसलिए मैं कहूंगा कि यह उनके सवाल का जवाब दिया :) मैंने सोचा कि मैं इसे एक आधुनिक विकल्प के रूप में पॉप करूंगा, और आशा है कि यह उन लोगों की मदद करता है जो यहां उतरते हैं। वास्तव में, मैंने इस प्रश्न में यह सब कवर किया है - मुझे उम्मीद है कि यह विधि जल्द ही एक regex को स्वीकार करेगी, हालांकि इसके ठीक नीचे आपके मामले के लिए एक सही विकल्प है।
15

316
irb> 'now is the time'[0...-4]
=> "now is the "

9
ध्यान दें कि यह केवल रूबी 1.9 में काम करता है। रूबी 1.8 में, यह अंतिम बाइट्स को हटा देगा , न कि अंतिम अक्षर
जोर्ग डब्ल्यू मित्तग

2
लेकिन वह शायद "बाइट्स" का मतलब था अगर वह 1.8.x का उपयोग कर रहा है।
DigitalRoss

4
यह काम करता है, लेकिन मैं 'abc123'.chomp (' 123 ') को शॉर्ट और बहुत लंबे स्ट्रिंग्स दोनों के लिए दो बार तेज होने के लिए पा रहा हूं। (रूबी 2.0.0-पी 247) क्या कोई इसकी पुष्टि कर सकता है?
प्लाज्मा प्लाज्मा

10
सोच रहे लोगों के लिए कि यह विशिष्ट उदाहरण क्यों काम नहीं करता [0...-4][0..-4]
है..तो

2
@Plamarob मुझे लगता है कि यह कहना अधिक प्रासंगिक है कि धूमधाम 53 नैनोसेकंड की तुलना में तेज है, यह कहना है कि यह दो बार तेज है। तब आप इसका उपयोग करने की लागत बनाम मूल्य का बेहतर अनुमान लगा सकते हैं, और क्या यह किसी दिए गए स्थिति में अनुकूलन की बात हो सकती है।
cesoid

266

यदि आप जिन पात्रों को हटाना चाहते हैं, वे हमेशा समान वर्ण हैं, तो विचार करें chomp:

'abc123'.chomp('123')    # => "abc"

इसके फायदे chompहैं: कोई गिनती नहीं, और कोड अधिक स्पष्ट रूप से यह बताता है कि यह क्या कर रहा है।

बिना किसी बहस के, chompडॉस या यूनिक्स लाइन को समाप्त कर देता है, यदि या तो मौजूद है:

"abc\n".chomp      # => "abc"
"abc\r\n".chomp    # => "abc"

टिप्पणियों से, #chompएक सीमा का उपयोग करके बनाम उपयोग करने की गति का सवाल था । यहाँ एक बेंचमार्क की तुलना दो है:

require 'benchmark'

S = 'asdfghjkl'
SL = S.length
T = 10_000
A = 1_000.times.map { |n| "#{n}#{S}" }

GC.disable

Benchmark.bmbm do |x|
  x.report('chomp') { T.times { A.each { |s| s.chomp(S) } } }
  x.report('range') { T.times { A.each { |s| s[0...-SL] } } }
end

बेंचमार्क परिणाम (CRuby 2.13p242 का उपयोग करके):

Rehearsal -----------------------------------------
chomp   1.540000   0.040000   1.580000 (  1.587908)
range   1.810000   0.200000   2.010000 (  2.011846)
-------------------------------- total: 3.590000sec

            user     system      total        real
chomp   1.550000   0.070000   1.620000 (  1.610362)
range   1.970000   0.170000   2.140000 (  2.146682)

तो एक सीमा का उपयोग करने से ~ 22% की तुलना में चॉम्प तेज होता है।


5
चॉप भी एक विकल्प है। यह कम हो जाता है के बारे में उधम मचाते हैं।
एंड्रयू ग्रिम 12

1
मैंने पाया कि वास्तव में विपरीत है। वास्तविकता यह है कि .chomp लगातार दुगनी तेजी से लगता है।
प्लाज़्माब्रोब

3
@Plamarob, रूबी में बेंचमार्क अक्सर आश्चर्यजनक होते हैं। मैं अक्सर गलत हूं कि मैं अब यह अनुमान लगाने की कोशिश नहीं करता हूं कि क्या तेज होगा। इसके अलावा, यदि उत्तर बेंचमार्क परिणामों से बेहतर होगा, तो कृपया इसे संपादित करने के लिए स्वतंत्र महसूस करें।
वेन कॉनराड

1
अगर मैं कोड को सही से पढ़ रहा हूं, तो सीमा लगभग 53 नैनोसेकंड की तुलना में अधिक समय लेती है। यह कुछ स्थितियों में एक महत्वपूर्ण खींच हो सकता है, लेकिन पूर्ण गति को ध्यान में रखते हुए (केवल रिश्तेदार के बजाय) आपको बता सकता है कि क्या आपको अपने कोडबेस के माध्यम से जाना चाहिए और अपनी सभी सीमाओं को chomps (जहां लागू हो) में बदलना चाहिए। शायद ऩही।
cesoid

1
बहुत अच्छा काम करता है। और आप chomp!()स्ट्रिंग-इन-इन पर कार्रवाई करने के लिए उपयोग कर सकते हैं ।
जोशुआ पिंटर

57
str = str[0...-n]

5
ध्यान दें कि यह केवल रूबी 1.9 में काम करता है। रूबी 1.8 में, यह अंतिम बाइट्स को हटा देगा , न कि अंतिम अक्षर
जोर्ग डब्ल्यू मित्तग

5
यह चुने हुए उत्तर से बेहतर है, क्योंकि 3 डॉट्स (...) को याद रखना आसान है क्योंकि एन का अर्थ स्ट्रिंग के अंत से एन वर्णों को बाहर निकालना है।
लूलालाल

"abcd" [0 ..- 2] # => "abc" जबकि "abcd" [0 ...- 2] # => "ab"। मेरी राय में 3 डॉट्स रेंज विकल्प के परिणामस्वरूप अधिक आत्म व्याख्यात्मक कोड होता है।
मोकागियो जूल

31

मैं सुझाव दूंगा chop। मुझे लगता है कि इसका उल्लेख टिप्पणियों में से एक में किया गया है, लेकिन लिंक या स्पष्टीकरण के बिना, इसलिए यहां मुझे लगता है कि यह बेहतर है:

यह केवल एक स्ट्रिंग से अंतिम वर्ण को निकालता है और आपको ऐसा करने के लिए कोई मान निर्दिष्ट करने की आवश्यकता नहीं है।

यदि आपको एक से अधिक चरित्रों को हटाने की आवश्यकता है तो chompआपका सबसे अच्छा दांव है। यह रूबी डॉक्स के बारे में क्या कहना है chop:

हटाए गए अंतिम वर्ण के साथ एक नया स्ट्रिंग लौटाता है। यदि स्ट्रिंग \ r \ n के साथ समाप्त होती है, तो दोनों वर्ण हटा दिए जाते हैं। एक खाली स्ट्रिंग में चॉप लगाने से एक खाली स्ट्रिंग लौट आती है। स्ट्रिंग # chomp अक्सर एक सुरक्षित विकल्प है, क्योंकि यह स्ट्रिंग को अपरिवर्तित छोड़ देता है यदि यह रिकॉर्ड विभाजक में समाप्त नहीं होता है।

हालाँकि इसका उपयोग ज्यादातर विभाजकों को हटाने के लिए किया जाता है जैसे कि \r\nमैंने इसे एक साधारण स्ट्रिंग से अंतिम वर्ण को हटाने के लिए उपयोग किया है, उदाहरण के sलिए शब्द एकवचन बनाने के लिए।


1
कि सिर्फ एक ही अंतिम चरित्र को दूर नहीं होगा? सवाल बहुवचन में "वर्ण" के बारे में है
2

1
हां, आप सही हैं, लेकिन chomp ('वर्ण') अंतिम 'वर्ण' को हटा देगा। यह स्पष्ट नहीं था कि अगर ओपी विशिष्ट वर्ण या सिर्फ एन वर्ण चाहता था।
काकूबाई

हां, यह जवाब है, केवल जब आप केवल एक चरित्र को निकालना चाहते हैं (जो मेरे साथ हालांकि मामला था)।
Quv

29
name = "my text"
x.times do name.chop! end

यहाँ कंसोल में:

>name = "Nabucodonosor"
 => "Nabucodonosor" 
> 7.times do name.chop! end
 => 7 
> name
 => "Nabuco" 

क्या यह कुशल है? अन्य उत्तरों की तुलना में बेंचमार्क के लायक एक लगता है :)
SRack

16

अंतिम nपात्रों को गिराना पहले length - nपात्रों को रखने के समान है ।

सक्रिय समर्थन भी शामिल है String#firstऔर String#lastतरीकों जो एक सुविधाजनक तरीका प्रदान करते हैं रखने या प्रथम / अंतिम ड्रॉप करने nवर्ण:

require 'active_support/core_ext/string/access'

"foobarbaz".first(3)  # => "foo"
"foobarbaz".first(-3) # => "foobar"
"foobarbaz".last(3)   # => "baz"
"foobarbaz".last(-3)  # => "barbaz"

7

यदि आप रेल का उपयोग कर रहे हैं, तो कोशिश करें:

"my_string".last(2) # => "ng"

[संपादित]

पिछले 2 वर्णों के बिना स्ट्रिंग प्राप्त करने के लिए:

n = "my_string".size
"my_string"[0..n-3] # => "my_stri"

नोट: अंतिम स्ट्रिंग चार n-1 पर है। इसलिए, अंतिम 2 को हटाने के लिए, हम n-3 का उपयोग करते हैं।


2
यह पिछले दो अक्षरों को नहीं हटाता है। यह उन्हें लौटाता है।
जेपी सिल्वाशी

1
आपको पहले स्ट्रिंग को मापने की आवश्यकता नहीं है, रूबी स्ट्रिंग के अंत से नकारात्मक अनुक्रमित का उपयोग करता है मूल रूप से
डेवोन पार्सन्स

3

आप हमेशा कुछ का उपयोग कर सकते हैं

 "string".sub!(/.{X}$/,'')

Xहटाने के लिए वर्णों की संख्या कहां है।

या परिणाम को असाइन करने / उपयोग करने के साथ:

myvar = "string"[0..-X]

हटाने के लिए Xवर्णों की संख्या प्लस एक कहां है ।



1

यदि आप क्लास मेथड बनाने के साथ ठीक हैं और चाहते हैं कि आपके द्वारा काटे गए पात्र हों, तो यह आज़माएँ:

class String
  def chop_multiple(amount)
    amount.times.inject([self, '']){ |(s, r)| [s.chop, r.prepend(s[-1])] }
  end
end

hello, world = "hello world".chop_multiple 5
hello #=> 'hello '
world #=> 'world'


0

यदि आप जिन पात्रों को हटाना चाहते हैं, वे हमेशा समान वर्ण हैं, तो धूमधाम पर विचार करें:

'abc123'। धूमधाम ('123')


-3
x = "my_test"
last_char = x.split('').last

3
प्रश्न एक स्ट्रिंग से अंतिम एन वर्णों को हटाने के बारे में था, न कि अंतिम चरित्र को खोजने के बारे में
अनावश्यक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.