Dizeden alt dizeyi kaldırın


198

Dizeyi başka bir dizeden kaldırmak için herhangi bir yöntem olup olmadığını merak ediyorum. Bunun gibi bir şey:

class String
  def remove(s)
    self[s.length, self.length - s.length]
  end
end

Yanıtlar:


267

Dilim yöntemini kullanabilirsiniz:

a = "foobar"
a.slice! "foo"
=> "foo"
a
=> "bar"

yok '!' versiyonu da. Diğer sürümlerle ilgili belgelerde de daha fazla bilgi bulunabilir: http://www.ruby-doc.org/core/classes/String.html#method-i-slice-21


1
Çok zarif! []Patlamayan sürüm için s de kullanabilirsiniz .
Matheus Moreira

67
Bunun, silinen metni (veya aranan metni) geri getirme gibi kötü bir yan etkisi vardır. Silme sonucu zincirleme yapmaktan talihsizlik.
Mike

10
Dilimlenmiş dizgiyi nasıl döndürür ve orijinali etkilemez? Örneğin, "merhaba dünyam" varsa, orijinal dize nesnesini değiştirmeden "merhaba" yı dilimlemek ve yalnızca "dünya" bölümünü döndürmek istiyorum?
jhabbott

14
@Mike"foobar".tap{|s| s.slice!("foo")}.upcase
Ernest

7
@bcackerman - geçtiğiniz deletetüm karakterleri sildiği için işe yaramaz:'hello world'.delete('hello') #=> ' wrd'
paslı

167

Nereden str.gsub("subString", "") kontrol edin Yakut Doc


38
subgsubOP, alt dizeyi dizenin tamamından değil, dizenin başından kaldırmak istediğinden daha uygun olacaktır (örnek koduna bakın). Ve bunun gibi bir normal ifade kullanmak daha iyi olur: str.sub(/^subString/, '')- çünkü alt dizenin kesinlikle yalnızca baştan kaldırılmasını sağlar.
Alex D

@AlexD Bir normal ifade kullanmak daha iyi olur, ancak subStringherhangi bir normal ifade özel karakterleri içermediğinden emin olamazsak tehlikelidir .
David Benler

@DavidMoles, bu durumda, birebirdir, bu /^subString/nedenle herhangi bir meta karakter içermediğinden çok emin olabiliriz. Eğer bir regex içine diğer bazı dize yerine iseniz, bunu yapabilirsiniz: /#{Regexp.escape(str)}/.
Alex D

Cevapta evet, ancak OP'nin sorusunda değil. Yine de işaretçi için teşekkürler Regexp.escape().
David Benler


46

Hedef dizenin yalnızca bir örneğine sahipseniz, kullanabilirsiniz:

str[target] = ''

veya

str.sub(target, '')

Birden çok kez hedef kullanımınız varsa:

str.gsub(target, '')

Örneğin:

asdf = 'foo bar'
asdf['bar'] = ''
asdf #=> "foo "

asdf = 'foo bar'
asdf.sub('bar', '') #=> "foo "
asdf = asdf + asdf #=> "foo barfoo bar"
asdf.gsub('bar', '') #=> "foo foo "

Tek yapmanız gereken ise yerinde değiştirmelerin kullanmak "!"sürümlerini gsub!ve sub!.


2
Ruby eğlencelidir! asdf['bar'] = ''
Şunlar

1
Ben buna "eğlence" demezdim - belki de sezgisel değildir.
Jmoney38

31

Rails kullanıyorsanız bir de var remove.

Örneğin "Testmessage".remove("message")verim "Test".

Uyarı: bu yöntem tüm olayları kaldırır


1
Bu vanilyalı bir Ruby cevabı değil, ancak kabul edilen cevap çoğu insanın aradığı şey değil. Maalesef, sliceyöntem dizginin dilimlenmiş kısmını döndürmez, "bıçak" ı döndürür
Dylan Pierce

1
@DylanPierce, bunu kullanan bir işlevi uygulamak oldukça kolaydırslice! def gimme_the_slice(my_string, my_slice) my_string.slice!(my_slice) my_string
Bennett Talpers

1
Ah bu doğru, şaşırtıcı bir şekilde Ruby'nin mevcut değişkeni nasıl değiştirdiği. Teşekkürler @BennettTalpers
Dylan Pierce



1

Doğru yorumluyorsam, bu soru dizeler arasında eksi (-) işlemi gibi bir şey istiyor gibi görünüyor, yani yerleşik artı (+) işleminin (birleştirme) tersi.

Önceki cevaplardan farklı olarak, özelliğe uyması gereken böyle bir işlem tanımlamaya çalışıyorum:

EĞER c = a + b SONRA c - a = b VE c - b = a

Bunu başarmak için yalnızca üç yerleşik Ruby yöntemine ihtiyacımız var:

'abracadabra'.partition('abra').values_at(0,2).join == 'cadabra'.

Nasıl çalıştığını açıklamayacağım çünkü her seferinde bir yöntemi çalıştırmanın kolayca anlaşılabilmesi.

İşte konsept kodunun bir kanıtı:

# minus_string.rb
class String
  def -(str)
    partition(str).values_at(0,2).join
  end
end

# Add the following code and issue 'ruby minus_string.rb' in the console to test
require 'minitest/autorun'

class MinusString_Test < MiniTest::Test

  A,B,C='abra','cadabra','abracadabra'

  def test_C_eq_A_plus_B
    assert C == A + B
  end

  def test_C_minus_A_eq_B
    assert C - A == B
  end

  def test_C_minus_B_eq_A
    assert C - B == A
  end

end

Yeni bir Ruby sürümü kullanıyorsanız (> = 2.0) son bir tavsiye: önceki örnekte olduğu gibi maymun yamalı String yerine Ayrıntılandırmaları kullanın.

Bu kadar kolay:

module MinusString
  refine String do
    def -(str)
      partition(str).values_at(0,2).join
    end
  end
end

ve using MinusStringihtiyacınız olan yerlere blokların önüne ekleyin .


İyileştirme kavramları için +1. Maymun yamalı String sınıfı muhtemelen bu kullanım durumu için aşırı bir şey olsa da, bazen bazı şeyleri yamalıyoruz ve iyileştirme kavramı gerçekten parlıyor.
wondersz1

-2

işte ne yapardım

2.2.1 :015 > class String; def remove!(start_index, end_index) (end_index - start_index + 1).times{ self.slice! start_index }; self end; end;
2.2.1 :016 >   "idliketodeleteHEREallthewaytoHEREplease".remove! 14, 32
 => "idliketodeleteplease" 
2.2.1 :017 > ":)".remove! 1,1
 => ":" 
2.2.1 :018 > "ohnoe!".remove! 2,4
 => "oh!" 

Birden çok satırda biçimlendirilmiş:

class String
    def remove!(start_index, end_index)
        (end_index - start_index + 1).times{ self.slice! start_index }
        self
    end 
end

-7
def replaceslug
  slug = "" + name
    @replacements = [
      [ "," , ""],
      [ "\\?" , ""],
      [ " " , "-"],
      [ "'" , "-"],
      [ "Ç" , "c"],
      [ "Ş" , "s"],
      [ "İ" , "i"],
      [ "I" , "i"],
      [ "Ü" , "u"],
      [ "Ö" , "o"],
      [ "Ğ" , "g"],
      [ "ç" , "c"],
      [ "ş" , "s"],
      [ "ı" , "i"],
      [ "ü" , "u"],
      [ "ö" , "o"],
      [ "ğ" , "g"],
    ]
  @replacements.each do |pair|
    slug.gsub!(pair[0], pair[1])
  end
  self.slug = slug.downcase
end

1
Neden bu kadar çok olumsuz oy var? Yanlış .. çok geniş belki ne yaptın
Zee

ÖÖrneğin OP kaldırılmasını istemedi .
Iulian Onofrei
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.