Cara memeriksa apakah string berisi substring di Ruby

731

Saya memiliki variabel string dengan konten:

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"

Dalam string saya harus menemukan sub-string:

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

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

Bagaimana saya bisa menemukannya? Saya perlu menentukan apakah sub-string ada atau tidak.

BSalunke
sumber
3
Pertanyaan terkait: stackoverflow.com/questions/3876246/…
Andrew Grimm
Lihat stackoverflow.com/a/3878656/128421 untuk rincian berbagai cara untuk melakukan ini.
Manusia Timah

Jawaban:

1366

Anda dapat menggunakan include?metode ini:

my_string = "abcdefg"
if my_string.include? "cde"
   puts "String includes 'cde'"
end
Adam Lear
sumber
103
Ingat itu include?peka huruf besar-kecil. Jadi jika my_stringdalam contoh di atas akan menjadi sesuatu seperti "abcDefg"(dengan huruf besar D), include?("cde")akan kembali false. Anda mungkin ingin melakukan downcase()sebelum menelepon include?().
phortx
4
Memasukkan sendiri itu tidak ideal karena dapat melempar NoMethodError jika nil test = nil test.include? ("Test") NoMethodError: metode yang tidak ditentukan `termasuk? ' untuk nil: NilClass harus selalu mengonversi nilai yang dimasukkan ke nilai yang diharapkan: - test.to_s.include? ("test")
Gary
@ Saran Gary berlaku jika tujuan Anda adalah untuk meminimalkan pengecualian yang muncul di bagian kode ini. Itu tidak selalu merupakan tujuan terbaik. Secara umum jika Anda mengharapkan string pada titik ini dalam kode dan nilainya nihil, yang menyiratkan sesuatu yang tidak terduga telah terjadi dan pengecualian yang diajukan adalah tepat. Jika keberadaan nil di sini tidak terduga, menggunakan to_sakan menyembunyikan masalah dan meningkatkan jarak antara sumber dan deteksi masalah, membuatnya lebih sulit untuk di-debug.
Luke Griffiths
88

Jika case tidak relevan, maka ekspresi reguler case-insensitive adalah solusi yang baik:

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

Ini juga akan berfungsi untuk string multi-line.

Lihat kelas Regexp Ruby untuk informasi lebih lanjut.

Clint Pachl
sumber
11
Jika Anda cocok dengan input pengguna dan menggunakan teknik ini, ingatlah untuk menggunakan Regexp.escapestring. Untuk sebagian besar kasus penggunaan, some_str.include? substr.downcase()harus bekerja lebih cepat dan lebih mudah dibaca.
Jack
4
Menggunakan ekspresi reguler dengan cara ini tidak selalu lebih cepat daripada menggunakan 'aBcDe'.downcase.include?('bcd'). Regex memiliki tujuan tetapi tidak menggunakannya saat metode bawaan lebih cepat. Benchmarking dengan data aktual yang sedang diuji dapat mengungkapkan banyak hal.
the Tin Man
3
Ini TIDAK mengevaluasi sebagai benar. Mengevaluasi ke 1 yang tidak benar.
slindsey3000
2
!! ('aBcDe' = ~ / bcd / i) akan mengevaluasi benar atau salah. Menggunakan !! idiom
slindsey3000
2
Atau, gunakan pertandingan? untuk mengembalikan boolean:/bcd/i.match?('aBcDe')
ferrell_io
45

Anda juga dapat melakukan ini ...

my_string = "Hello world"

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

# => 'It has "Hello"'

Contoh ini menggunakan #[]metode String Ruby .

Oto Brglez
sumber
2
Ini adalah trik rapi yang belum pernah saya lihat sebelumnya. Namun #include?masih sedikit lebih cepat.
Scott Schupbach
4
#include?tidak berfungsi ketika Anda bekerja dengan kalimat dengan spasi di dalam karena #includememisahkan kalimat dalam kata-kata dan kemudian menggunakan kata-kata sebagai nilai array terpisah. Ini berfungsi dengan baik untuk kalimat. +1
luissimo
Lihat []metode String Ruby untuk informasi lebih lanjut.
the Tin Man
32

Memperluas jawaban Clint Pachl:

Pencocokan Regex di Ruby kembali nilketika ekspresi tidak cocok. Ketika itu terjadi, itu mengembalikan indeks karakter di mana pertandingan terjadi. Sebagai contoh:

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

Penting untuk dicatat bahwa hanya di Ruby nildan ekspresi boolean falsebernilai false. Segala sesuatu yang lain, termasuk Array kosong, Hash kosong, atau Integer 0, bernilai true.

Itu sebabnya /foo/contoh di atas berfungsi, dan mengapa.

if "string" =~ /regex/

berfungsi seperti yang diharapkan, hanya memasuki bagian 'benar' dari ifblok jika terjadi kecocokan.

acib708
sumber
21

Ungkapan yang lebih ringkas daripada jawaban yang diterima di atas yang tersedia di Rails (dari 3.1.0 ke atas) adalah .in?:

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

Saya juga berpikir itu lebih mudah dibaca.

Lihat in?dokumentasi untuk informasi lebih lanjut.

Perhatikan lagi bahwa itu hanya tersedia di Rails , dan bukan Ruby murni.

stwr667
sumber
2
Ini bergantung pada rel, OP meminta solusi ruby
dft
2
Itu benar, meskipun karena sebagian besar pengembang Ruby menggunakan Rails, saya pikir ini mungkin solusi yang lebih disukai untuk beberapa karena kejelasan dan singkatnya.
stwr667
1
Lihat stackoverflow.com/a/4239625/128421 . Itu ada di Rails, tetapi mudah diakses dari Ruby biasa menggunakan Ekstensi Inti Dukungan Aktif Rails yang memungkinkan pemungutan ceri yang mudah dari kelompok kecil metode seperti hanya in?.
Manusia Timah
Benar @ theTinMan. "cde".in? my_stringdalam hasil Ruby murni NoMethodError. Tetapi dengan require 'active_support/core_ext/object/inclusion'itu berfungsi, yang dapat diambil baik dari Rails sendiri atau dari Cut-down Active Support Extensions .
stwr667
16

Cara ternary

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

ATAU

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

Anda dapat menggunakan metode Referensi Elemen String yang[]

Di dalam []dapat berupa substring literal, indeks, atau regex:

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

Karena nilsecara fungsional sama dengan falsedan setiap substring kembali dari []adalah trueAnda dapat menggunakan logika seperti jika Anda menggunakan metode .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" 

Pastikan Anda tidak mengacaukan indeks dengan sub-string:

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

Anda juga dapat menggunakan regex:

> s[/A/i]
=> "a"
> s[/A/]
=> nil
dawg
sumber
2
ini sangat fenomenal
Craig
3

Bagaimana cara memeriksa apakah string berisi substring di Ruby?

Ketika Anda mengatakan 'centang', saya berasumsi Anda ingin boolean dikembalikan dalam hal ini Anda dapat menggunakan String#match?. match?menerima string atau regex sebagai parameter pertama, jika yang pertama maka secara otomatis dikonversi ke regex. Jadi, use case Anda adalah:

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

String#match?memiliki manfaat tambahan dari argumen kedua opsional yang menentukan indeks untuk mencari string. Secara default ini diatur ke 0.

str.match? 'tri',0   #=> true
str.match? 'tri',1   #=> true
str.match? 'tri',2   #=> false
Sagar Pandya
sumber
2
user_input = gets.chomp
user_input.downcase!

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

Ini akan membantu Anda memeriksa apakah string berisi substring atau tidak

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
Prabhakar Undurthi
sumber