810 votes

Comment vérifier si une chaîne contient une sous-chaîne en Ruby ?

J'ai une variable de type chaîne dont le contenu est le suivant :

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"

dans la chaîne ci-dessus, je dois trouver une sous-chaîne, à savoir

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

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

Comment puis-je le trouver ? J'ai juste besoin de déterminer si la sous-chaîne est présente ou non.

3 votes

0 votes

Voir stackoverflow.com/a/3878656/128421 pour connaître les différentes façons de procéder.

1497voto

Anna Lear Points 13919

Vous pouvez utiliser le include? méthode :

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

115 votes

Rappelez-vous que include? est sensible à la casse. Ainsi, si my_string dans l'exemple ci-dessus serait quelque chose comme "abcDefg" (avec une majuscule D ), include?("cde") rendrait false . Vous pouvez faire un downcase() avant d'appeler include?() .

4 votes

Include seul n'est pas idéal car il peut lancer un NoMethodError if nil test = nil test.include ?("test") NoMethodError : undefined method `include?' for nil:NilClass should always convert the value being included to the expected value:- test.to_s.include ?("test")

3 votes

Le conseil de @Gary tient si votre objectif est de minimiser les exceptions soulevées dans cette partie du code. Ce n'est pas toujours le meilleur objectif. Généralement, si vous attendez une chaîne de caractères à cet endroit du code et qu'une valeur est nulle à la place, cela implique que quelque chose d'inattendu s'est produit et qu'il est approprié de lever une exception. Si l'existence d'un nil ici est inattendue, l'utilisation de la fonction to_s masquera le problème et augmentera la distance entre la source et la détection du problème, ce qui le rendra plus difficile à déboguer.

100voto

Clint Pachl Points 1153

Si le cas n'est pas pertinent, alors un expression régulière insensible à la casse est une bonne solution :

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

Cela fonctionnera également pour les chaînes de caractères à plusieurs lignes.

Voir le site de Ruby Regexp classe.

15 votes

Si vous effectuez une comparaison avec l'entrée de l'utilisateur et que vous utilisez cette technique, n'oubliez pas d'utiliser l'option Regexp.escape sur la chaîne de caractères. Pour la plupart des cas d'utilisation, some_str.include? substr.downcase() devrait fonctionner plus rapidement et être plus lisible.

8 votes

L'utilisation d'une expression régulière de cette manière ne sera pas nécessairement plus rapide que celle de l'expression régulière suivante 'aBcDe'.downcase.include?('bcd') . Les Regex ont leur utilité, mais il ne faut pas les utiliser lorsque les méthodes intégrées sont plus rapides. L'analyse comparative avec les données réelles testées peut être très révélatrice.

4 votes

Ceci n'est PAS évalué comme vrai. Elle est évaluée à 1, ce qui n'est pas vrai.

62voto

Oto Brglez Points 784

Vous pouvez aussi faire ça...

my_string = "Hello world"

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

# => 'It has "Hello"'

3 votes

C'est une astuce que je n'avais jamais vue auparavant. Mais #include? est toujours un peu plus rapide.

5 votes

#include? ne fonctionne pas lorsque vous travaillez avec des phrases contenant des espaces car #include divise la phrase en mots, puis utilise les mots comme des valeurs de tableau distinctes. Cela fonctionne parfaitement pour les phrases. +1

1 votes

Voir la chaîne de caractères de Ruby [] pour plus d'informations.

34voto

Développant la réponse de Clint Pachl :

La correspondance Regex en Ruby renvoie nil lorsque l'expression ne correspond pas. Lorsqu'elle le fait, elle renvoie l'index du caractère où la correspondance a lieu. Par exemple :

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

Il est important de noter qu'en Ruby, seule la fonction nil et l'expression booléenne false évaluent à faux. Tout le reste, y compris un tableau vide, un hachage vide ou le nombre entier 0, est évalué à true.

C'est pourquoi le /foo/ L'exemple ci-dessus fonctionne, et pourquoi.

if "string" =~ /regex/

fonctionne comme prévu, en n'entrant que la partie "vraie" de l'adresse IP. if si une correspondance s'est produite.

0 votes

if( ("foobar" =~ /foo/) == nil ) puts 'Not Found' else puts 'Found' end Cela devrait fonctionner.

23voto

stwr667 Points 161

Un idiome plus succinct que la réponse acceptée ci-dessus, disponible dans Rails (à partir de la version 3.1.0), est le suivant .in? :

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

Je pense aussi que c'est plus lisible.

Voir le in? pour plus d'informations.

Notez à nouveau qu'il n'est disponible que dans Rails et non du pur Ruby.

5 votes

Cela repose sur rails, le PO a demandé une solution ruby.

3 votes

C'est exact, mais comme une proportion importante de développeurs Ruby utilisent Rails, j'ai pensé que cette solution pourrait être privilégiée par certains en raison de sa clarté et de sa brièveté.

1 votes

Voir stackoverflow.com/a/4239625/128421 . Il se trouve dans Rails, mais on peut y accéder facilement à partir d'un Ruby normal en utilisant la fonction de Rails. Extensions de base du support actif qui permettent de sélectionner facilement de petits groupes de méthodes, comme par exemple seulement in? .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X