Come verificare se una stringa contiene una sottostringa in Ruby


731

Ho una variabile stringa con contenuto:

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"

Nella stringa devo trovare una sottostringa:

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

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

Come posso trovarlo? Devo determinare se la sottostringa è presente o meno.



Vedi stackoverflow.com/a/3878656/128421 per una ripartizione dei vari modi per farlo.
Tin Man,

Risposte:


1366

Puoi usare il include?metodo:

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

103
Ricorda che include?è sensibile al maiuscolo / minuscolo. Quindi, se my_stringnell'esempio sopra fosse qualcosa di simile "abcDefg"(con una maiuscola D), include?("cde")ritornerebbe false. Potresti voler fare un downcase()prima di chiamare include?().
phortx,

4
Includere da solo non è l'ideale in quanto può generare un NoMethodError se nil test = nil test.include? ("Test") NoMethodError: metodo indefinito `include? ' per zero: NilClass dovrebbe sempre convertire il valore incluso nel valore previsto: - test.to_s.include? ("test")
Gary

Il consiglio di @ Gary vale se il tuo obiettivo è ridurre al minimo le eccezioni sollevate in questa parte del codice. Questo non è sempre l'obiettivo migliore. Generalmente se ci si aspetta una stringa a questo punto nel codice e invece un valore è zero, ciò implica che si è verificato qualcosa di imprevisto e che viene sollevata un'eccezione. Se l'esistenza di uno zero qui è inaspettata, l'utilizzo to_snasconderà il problema e aumenterà la distanza tra la sorgente e il rilevamento del problema, rendendo più difficile il debug.
Luke Griffiths,

88

Se il caso è irrilevante, un'espressione regolare senza distinzione tra maiuscole e minuscole è una buona soluzione:

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

Questo funzionerà anche con stringhe multilinea.

Vedi la classe Regexp di Ruby per maggiori informazioni.


11
Se si esegue la corrispondenza con l'input dell'utente e si utilizza questa tecnica, ricordare di utilizzare Regexp.escapesulla stringa. Per la maggior parte dei casi d'uso, some_str.include? substr.downcase()dovrebbe funzionare più velocemente ed essere più leggibile.
Jack

4
Usare un'espressione regolare in questo modo non sarà necessariamente più veloce dell'uso 'aBcDe'.downcase.include?('bcd'). Regex ha il suo scopo ma non li usa quando i metodi integrati sono più veloci. Il benchmarking con i dati effettivi in ​​fase di test può rivelare molto.
Tin Man,

3
Questo NON viene valutato come vero. Valuta 1, il che non è vero.
slindsey3000,

2
!! ('aBcDe' = ~ / bcd / i) valuterà come vero o falso. Usa il !! idioma
slindsey3000

2
in alternativa, usa match? per restituire un valore booleano:/bcd/i.match?('aBcDe')
ferrell_io

45

Puoi anche farlo ...

my_string = "Hello world"

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

# => 'It has "Hello"'

Questo esempio usa il #[]metodo String di Ruby .


2
Questo è un trucco che non ho mai visto prima. Ma #include?è ancora un po 'più veloce.
Scott Schupbach,

4
#include?non funziona quando si lavora con frasi con spazi interni perché #includedivide la frase in parole e quindi utilizza le parole come valori di matrice separati. Questo funziona perfettamente per le frasi. +1
luissimo

Vedi il []metodo String di Ruby per maggiori informazioni.
Tin Man,

32

Espandendo la risposta di Clint Pachl:

La corrispondenza del Regex in Ruby ritorna nilquando l'espressione non corrisponde. Quando lo fa, restituisce l'indice del personaggio in cui si verifica l'incontro. Per esempio:

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

È importante notare che solo in Ruby nile l'espressione booleana vengono falsevalutate come false. Tutto il resto, incluso un array vuoto, un hash vuoto o il numero intero 0, viene considerato vero.

Ecco perché l' /foo/esempio sopra funziona e perché.

if "string" =~ /regex/

funziona come previsto, inserendo la parte "vera" del ifblocco solo se si verifica una corrispondenza.


21

Un linguaggio più succinto della risposta accettata sopra che è disponibile in Rails (dalla 3.1.0 in poi) è .in?:

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

Penso anche che sia più leggibile.

Vedere la in?documentazione per ulteriori informazioni.

Nota di nuovo che è disponibile solo in Rails e non in puro Ruby.


2
Questo si basa su binari, l'OP ha chiesto una soluzione ruby
dft

2
Esatto, anche se dal momento che una parte significativa degli sviluppatori di Ruby utilizza Rails, ho pensato che questa potrebbe essere una soluzione preferita per alcuni a causa della sua chiarezza e brevità.
stwr667,

1
Vedi stackoverflow.com/a/4239625/128421 . È in Rails, ma è facilmente accessibile dal normale Ruby utilizzando le estensioni del core di supporto attivo di Rails che consentono di selezionare facilmente piccoli gruppi di metodi come solo in?.
Tin Man,

Corretto @theTinMan. "cde".in? my_stringin puro rendimento rubino NoMethodError. Ma con require 'active_support/core_ext/object/inclusion'esso funziona, che può essere caricato da Rails stesso o dalle estensioni core di supporto attivo ridotte .
stwr667,

16

Modo ternario

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

O

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

11

È possibile utilizzare il metodo String Element Reference che è[]

All'interno []può esserci una sottostringa letterale, un indice o una regex:

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

Poiché nilè funzionalmente uguale falsee qualsiasi sottostringa restituita []è trueche è possibile utilizzare la logica come se si utilizza il metodo .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" 

Assicurati solo di non confondere un indice con una sottostringa:

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

Puoi anche usare un regex:

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

2
questo è fenomenale
Craig,

3

Come verificare se una stringa contiene una sottostringa in Ruby?

Quando dici "check", presumo che tu voglia restituire un booleano, nel qual caso puoi usarlo String#match?. match?accetta stringhe o regex come primo parametro, se è il primo viene automaticamente convertito in regex. Quindi il tuo caso d'uso sarebbe:

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

String#match?ha il vantaggio aggiuntivo di un secondo argomento facoltativo che specifica un indice da cui cercare la stringa. Per impostazione predefinita, questo è impostato su 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

Questo ti aiuterà a verificare se la stringa contiene o meno una sottostringa

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.