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.



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

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.


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 .


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.


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.


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')

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

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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.