Ruby'de bir dizeden belirli karakterler nasıl silinir?


85

Buna benzeyen birkaç dizim var:

"((String1))"

Hepsi farklı uzunluklardadır. Bir döngüde tüm bu dizelerden parantezleri nasıl kaldırabilirim?


2
Parantezleri mi yoksa "rastgele" bir dizeden ilk iki ve son iki karakteri mi kaldırmak istiyorsunuz? (Aslında rastgele mi?)
Monica'yı eski durumuna getir - notmaynard

"((String1))" [2 ...- 2] # => "String1"
Yeniden etkinleştir Monica - notmaynard


Birçok dizgeyi değiştirmek için bir döngü istiyorsunuz, dizeler nasıl saklanır?
hirolau

Tüm dizeleri nasıl döngüye alacağımı biliyorum, sadece dize manipülasyon kısmını istedim, üzgünüm bunu tuhaf söyledim
Cristiano

Yanıtlar:


168

Aşağıdakileri kullanarak yapın String#tr:

 "((String1))".tr('()', '')
 # => "String1"

7
tr!Bir dizeyi yerinde değiştirecek yıkıcı bir sürüm de var , örneğinmy_string.tr!(')(','')
bonh

8
Bu işlevin baştan veya sondan kırpılmadığını, dizedeki tüm metnin tam yerini aldığını unutmayın.
Jordan

3
Yanıltıcı ve yanlış. Tr bir kırpma işlevi değildir, bir değiştirme işlevidir. İkisi çok farklı operasyonlardır.
Zane Claes

1
@ZaneClaes Evet. OP, aslında OP'nin ne istediğini açıklamak için yanlış terim kullandı. Cevap, çıktıya nasıl ulaşılacağını gösterdi.
Arup Rakshit

42

Yalnızca ilk iki karakteri ve son ikisini kaldırmak istiyorsanız , dizede negatif dizinler kullanabilirsiniz :

s = "((String1))"
s = s[2...-2]
p s # => "String1"

Dizeden tüm parantezleri kaldırmak istiyorsanız , dize sınıfında silme yöntemini kullanabilirsiniz :

s = "((String1))"
s.delete! '()'
p s #  => "String1"

8
Bu, dizenin ortasındakiler de dahil olmak üzere tüm parantezleri silecektir, ki bu (görünüşte) OP'nin istediği şey değildir. İstenilen buysa en şık çözüm budur.
Monica'yı eski durumuna getir - notmaynard

22

O bu genelinde geliyor ve performans arayan için, benziyor #deleteve #tr2-4x daha hızlı hız aynı ve hakkındadır gsub.

text = "Here is a string with / some forwa/rd slashes"
tr = Benchmark.measure { 10000.times { text.tr('/', '') } }
# tr.total => 0.01
delete = Benchmark.measure { 10000.times { text.delete('/') } }
# delete.total => 0.01
gsub = Benchmark.measure { 10000.times { text.gsub('/', '') } }
# gsub.total => 0.02 - 0.04

3
Dört yıl sonra ... :-) Eğer kıyaslamanızı birkaç büyüklük sırasına göre yükseltirsem (1_000_000 çalıştırma), yukarıda kullandığınız aynı kodla, tr'den biraz daha hızlı bir şekilde siliyorum, yaklaşık olarak sil 0,92 oranında tr ve gsub 1,5x'den biraz daha az silme (aslında ~ 1,46 silme ve ~ 1,39 tr). elbette ymmv. Bu Ruby 2.6.3'te 2018 MBP 13'tedir. Bu üç yöntemi karşılaştırdığınız için teşekkürler!
likethesky

21

String#gsubNormal ifadeyle kullanmak :

"((String1))".gsub(/^\(+|\)+$/, '')
# => "String1"
"(((((( parentheses )))".gsub(/^\(+|\)+$/, '')
# => " parentheses "

Bu, yalnızca çevreleyen parantezleri kaldıracaktır.

"(((((( This (is) string )))".gsub(/^\(+|\)+$/, '')
# => " This (is) string "

2
İkinci örnek için +1 (yalnızca çevreleyen parantezleri kaldırın).
Bhavneet Singh Bajwa

1

İşte bunu başarmanın daha da kısa bir yolu:

1) kullanarak Negative character class pattern matching

irb(main)> "((String1))"[/[^()]+/]
=> "String1"

^- Karakter sınıfında OLMAYAN herhangi bir şeyle eşleşir. Charachter sınıfının içinde (ve)

Veya diğerleri gibi küresel ikame "AKA: gsub" ile.

irb(main)> "((String1))".gsub(/[)(]/, '')
=> "String1"

İki cevabınızın farklı sonuçları var ((a))b. Birincisi sadece geri dönecek a, ikincisi geri dönecekab
Ulysse BN
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.