Bir dizenin Ruby'de bir alt dize içerip içermediğini kontrol etme


731

İçeriği olan bir dize değişkeni var:

varMessage =   
            "hi/thsid/sdfhsjdf/dfjsd/sdjfsdn\n"


            "/my/name/is/balaji.so\n"
            "call::myFunction(int const&)\n"
            "void::secondFunction(char const&)\n"
             .
             .
             .
            "this/is/last/line/liobrary.so"

Dize bir alt dize bulmak zorunda:

"hi/thsid/sdfhsjdf/dfjsd/sdjfsdn\n"

"/my/name/is/balaji.so\n"
"call::myFunction(int const&)\n"

Nasıl bulabilirim? Alt dize olup olmadığını belirlemek gerekir.



Bkz stackoverflow.com/a/3878656/128421 Bunu yapmak için çeşitli yollar dökümünü.
Tin Man

Yanıtlar:


1365

include?Yöntemi kullanabilirsiniz :

my_string = "abcdefg"
if my_string.include? "cde"
   puts "String includes 'cde'"
end

102
Unutmayın ki include?bu durum hassastır. Dolayısıyla my_string, yukarıdaki örnekte "abcDefg"(büyük harfli D) bir şey include?("cde")olsaydı, geri dönecekti false. downcase()Aramadan önce yapmak isteyebilirsiniz include?().
phortx

4
Kendi başına dahil etmek, nil test = nil test.include? ("Test") olarak bir NoMethodError atabileceği için ideal değildir NoMethodError: undefined yöntemi `include? ' Nil için: NilClass her zaman dahil edilen değeri beklenen değere dönüştürmelidir: - test.to_s.include? ("test")
Gary

@ Gary'nin tavsiyesi tutan eğer amacınız bu kod parçası büyüdü istisnalar minimize etmektir. Bu her zaman en iyi hedef değildir. Genellikle kodun bu noktasında bir dize bekliyorsanız ve bunun yerine bir değer nil ise, bu beklenmedik bir şey meydana geldiğini ve bir özel durumun yükseldiğini gösterir. Burada bir nil varlığı beklenmedikse, kullanmak to_ssorunu gizleyecek ve kaynak ile sorunun algılanması arasındaki mesafeyi artıracak ve hata ayıklamayı zorlaştıracaktır.
Luke Griffiths

88

Durum ilgisizse, büyük / küçük harf duyarsız bir düzenli ifade iyi bir çözümdür:

'aBcDe' =~ /bcd/i  # evaluates as true

Bu, çok satırlı dizelerde de çalışır.

Daha fazla bilgi için Ruby'nin Regexp sınıfına bakın .


11
Kullanıcı girdisiyle eşleşiyorsanız ve bu tekniği kullanıyorsanız Regexp.escape, dizede kullanmayı unutmayın . Çoğu kullanım durumunda, some_str.include? substr.downcase()daha hızlı çalışmalı ve daha okunabilir olmalıdır.
Jack

4
Normal bir ifadeyi bu şekilde kullanmak, kullanmaktan daha hızlı olmayacaktır 'aBcDe'.downcase.include?('bcd'). Regex'in amacı vardır, ancak yerleşik yöntemler daha hızlı olduğunda bunları kullanmayın. Test edilen gerçek verilerle kıyaslama çok fazla şey ortaya çıkarabilir.
Teneke Adam

3
Bu doğru olarak DEĞİLDİR. Doğru olmayan 1 olarak değerlendirilir.
slindsey3000

2
!! ('aBcDe' = ~ / bcd / i) doğru veya yanlış olarak değerlendirilir. Kullan !! deyim
slindsey3000 16:18

2
alternatif olarak, eşleşme kullanılsın mı? bir boole döndürmek için:/bcd/i.match?('aBcDe')
ferrell_io

45

Bunu da yapabilirsiniz ...

my_string = "Hello world"

if my_string["Hello"]
  puts 'It has "Hello"'
else
  puts 'No "Hello" found'
end

# => 'It has "Hello"'

Bu örnekte Ruby'nin String #[]yöntemi kullanılmıştır.


2
Bu daha önce görmediğim düzgün bir numara. Ama #include?yine de biraz daha hızlı.
Scott Schupbach

4
#include?içindeki boşlukları olan cümlelerle çalışırken işe yaramaz çünkü #includecümleyi kelimelere ayırır ve daha sonra kelimeleri ayrı dizi değerleri olarak kullanır. Bu cümleler için mükemmel çalışır. +1
luissimo

Daha []fazla bilgi için Ruby'nin String yöntemine bakın .
Tin Man

32

Clint Pachl'ın cevabına genişleyen:

nilİfade eşleşmediğinde Ruby'deki normal ifade eşleşmesi döndürülür . Bu gerçekleştiğinde, eşleşmenin gerçekleştiği karakterin dizinini döndürür. Örneğin:

"foobar" =~ /bar/  # returns 3
"foobar" =~ /foo/  # returns 0
"foobar" =~ /zzz/  # returns nil

Yalnızca Ruby'de nilve boole ifadesinin falseyanlış olarak değerlendirildiğini belirtmek önemlidir . Boş bir Dizi, boş Karma veya Tamsayı 0 dahil olmak üzere diğer her şey doğru olarak değerlendirilir.

Bu yüzden /foo/yukarıdaki örnek işe yarıyor ve neden.

if "string" =~ /regex/

beklendiği gibi çalışır, yalnızca ifbir eşleşme gerçekleştiğinde bloğun 'true' kısmını girer .


21

Rails'te (3.1.0 ve üstü) bulunan yukarıdaki kabul edilen cevaptan daha özlü bir deyim .in?:

my_string = "abcdefg"
if "cde".in? my_string
  puts "'cde' is in the String."
  puts "i.e. String includes 'cde'"
end

Ayrıca daha okunabilir olduğunu düşünüyorum.

Daha in?fazla bilgi için belgelere bakın .

Sadece Rails'te mevcut olduğunu ve saf Ruby'de olmadığını unutmayın.


2
Bu raylara dayanıyor, OP yakut bir çözüm istedi
dft

2
Bu doğru, ancak Ruby geliştiricilerinin önemli bir kısmı Rails kullandığından, bunun netliği ve kısalığı nedeniyle bazıları için tercih edilen bir çözüm olabileceğini düşündüm.
stwr667

1
Bkz. Stackoverflow.com/a/4239625/128421 . Raylar içinde ama kolayca Rails'in kullanarak düzenli Ruby erişilir Aktif Destek Çekirdek Extensions böyle yalnızca yöntemlerin küçük gruplar kolayca kiraz toplamaya imkan vermek in?.
Tin Man

Doğru @TinMan. "cde".in? my_stringSaf yakut verim NoMethodError. Ancak require 'active_support/core_ext/object/inclusion', Rails'in kendisinden veya cut-down Aktif Destek Çekirdek Uzantılarından yüklenebilen çalışır .
stwr667

16

Üçlü yol

my_string.include?('ahr') ? (puts 'String includes ahr') : (puts 'String does not include ahr')

VEYA

puts (my_string.include?('ahr') ? 'String includes ahr' : 'String not includes ahr')

11

Dize öğesi başvurusu yöntemini kullanabilirsiniz.[]

Kutunun içinde []değişmez bir alt dize, bir dizin veya bir normal ifade olabilir:

> s='abcdefg'
=> "abcdefg"
> s['a']
=> "a"
> s['z']
=> nil

Yana nilişlevsel aynıdır falseve dönen herhangi alt dize []olduğunu truesen yöntemi kullanmak sanki sen mantığı kullanabilirsiniz .include?:

0> if s[sub_s]
1>    puts "\"#{s}\" has \"#{sub_s}\""
1> else 
1*    puts "\"#{s}\" does not have \"#{sub_s}\""
1> end
"abcdefg" has "abc"

0> if s[sub_s]
1>    puts "\"#{s}\" has \"#{sub_s}\""
1> else 
1*    puts "\"#{s}\" does not have \"#{sub_s}\""
1> end
"abcdefg" does not have "xyz" 

Bir dizini bir alt dizeyle karıştırmamaya dikkat edin:

> '123456790'[8]    # integer is eighth element, or '0'
=> "0"              # would test as 'true' in Ruby
> '123456790'['8']  
=> nil              # correct

Bir normal ifadeyi de kullanabilirsiniz:

> s[/A/i]
=> "a"
> s[/A/]
=> nil

2
bu olağanüstü
Craig

3

Bir dizenin Ruby'de bir alt dize içerip içermediğini nasıl kontrol edebilirim?

'Kontrol' dediğinizde, kullanabileceğiniz bir boole döndürülmesini istediğinizi varsayalım String#match?. match?dizeleri veya normal ifadeleri ilk parametresi olarak kabul eder, eğer eski ise otomatik olarak normal ifadeye dönüştürülür. Yani kullanım durumunuz:

str = 'string'
str.match? 'strings' #=> false
str.match? 'string'  #=> true
str.match? 'strin'   #=> true
str.match? 'trin'    #=> true
str.match? 'tri'     #=> true

String#match?, dizeyi aramak için kullanılacak bir dizini belirten isteğe bağlı ikinci bir bağımsız değişkenin ek avantajına sahiptir. Varsayılan olarak bu, olarak ayarlanır 0.

str.match? 'tri',0   #=> true
str.match? 'tri',1   #=> true
str.match? 'tri',2   #=> false

2
user_input = gets.chomp
user_input.downcase!

if user_input.include?('substring')
  # Do something
end

Bu, dizenin alt dize içerip içermediğini kontrol etmenize yardımcı olur

puts "Enter a string"
user_input = gets.chomp  # Ex: Tommy
user_input.downcase!    #  tommy


if user_input.include?('s')
    puts "Found"
else
    puts "Not found"
end
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.