So überprüfen Sie, ob eine Zeichenfolge in Ruby eine Teilzeichenfolge enthält

731

Ich habe eine Stringvariable mit Inhalt:

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"

In der Zeichenfolge muss ich eine Unterzeichenfolge finden:

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

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

Wie kann ich es finden? Ich muss feststellen, ob der Teilstring vorhanden ist oder nicht.

BSalunke
quelle
3
Verwandte Frage: stackoverflow.com/questions/3876246/…
Andrew Grimm
Unter stackoverflow.com/a/3878656/128421 finden Sie eine Aufschlüsselung der verschiedenen Möglichkeiten, dies zu tun.
Der Blechmann

Antworten:

1365

Sie können die include?Methode verwenden:

my_string = "abcdefg"
if my_string.include? "cde"
   puts "String includes 'cde'"
end
Adam Lear
quelle
102
Denken Sie daran, dass include?dies fallempfindlich ist. Wenn also my_stringim obigen Beispiel so etwas wie "abcDefg"(mit einem Großbuchstaben D) include?("cde")wäre , würde zurückkehren false. Möglicherweise möchten Sie eine downcase()vor dem Anruf durchführen include?().
Phortx
4
Einschließen allein ist nicht ideal, da es einen NoMethodError auslösen kann, wenn nil test = nil test.include? ("Test") NoMethodError: undefinierte Methode `include? ' für nil: NilClass sollte den eingeschlossenen Wert immer in den erwarteten Wert konvertieren: - test.to_s.include? ("test")
Gary
@ Garys Rat gilt, wenn Ihr Ziel darin besteht, die in diesem Teil des Codes angesprochenen Ausnahmen zu minimieren. Das ist nicht immer das beste Ziel. Wenn Sie an dieser Stelle im Code eine Zeichenfolge erwarten und stattdessen ein Wert von Null ist, bedeutet dies im Allgemeinen, dass etwas Unerwartetes aufgetreten ist und eine Ausnahme ausgelöst wird. Wenn das Vorhandensein einer Null hier unerwartet ist, to_swird das Problem durch Verwendung von ausgeblendet und der Abstand zwischen der Quelle und der Erkennung des Problems vergrößert, wodurch das Debuggen erschwert wird.
Luke Griffiths
88

Wenn der Fall irrelevant ist, ist ein regulärer Ausdruck ohne Berücksichtigung der Groß- und Kleinschreibung eine gute Lösung:

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

Dies funktioniert auch für mehrzeilige Zeichenfolgen.

Weitere Informationen finden Sie in Rubys Regexp- Klasse.

Clint Pachl
quelle
11
Wenn Sie mit Benutzereingaben übereinstimmen und diese Technik verwenden, denken Sie daran, sie Regexp.escapefür die Zeichenfolge zu verwenden. Für die meisten Anwendungsfälle some_str.include? substr.downcase()sollte schneller arbeiten und besser lesbar sein.
Jack
4
Die Verwendung eines regulären Ausdrucks auf diese Weise ist nicht unbedingt schneller als die Verwendung 'aBcDe'.downcase.include?('bcd'). Regex haben ihren Zweck, verwenden sie jedoch nicht, wenn die integrierten Methoden schneller sind. Das Benchmarking mit den tatsächlich getesteten Daten kann viel verraten.
der Blechmann
3
Dies wird NICHT als wahr bewertet. Es ergibt 1, was nicht wahr ist.
Slindsey3000
2
!! ('aBcDe' = ~ / bcd / i) wird als wahr oder falsch bewertet. Verwenden Sie die !! idiom
slindsey3000
2
Alternativ Match verwenden? um einen Booleschen /bcd/i.match?('aBcDe')
Wert
45

Sie können dies auch tun ...

my_string = "Hello world"

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

# => 'It has "Hello"'

In diesem Beispiel wird die Ruby-String- #[]Methode verwendet.

Oto Brglez
quelle
2
Dies ist ein ordentlicher Trick, den ich noch nie gesehen habe. Ist #include?aber noch etwas schneller.
Scott Schupbach
4
#include?funktioniert nicht, wenn Sie mit Sätzen mit Leerzeichen arbeiten, da #includeder Satz in Wörter aufgeteilt wird und die Wörter dann als separate Array-Werte verwendet werden. Dies funktioniert perfekt für Sätze. +1
Luissimo
[]Weitere Informationen finden Sie unter Ruby's String- Methode.
Der Blechmann
32

Erweiterung der Antwort von Clint Pachl:

Die Regex-Übereinstimmung in Ruby wird zurückgegeben, nilwenn der Ausdruck nicht übereinstimmt. Wenn dies der Fall ist, wird der Index des Zeichens zurückgegeben, in dem die Übereinstimmung stattfindet. Zum Beispiel:

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

Es ist wichtig zu beachten, dass nur in Ruby nilund der boolesche Ausdruck falseals falsch ausgewertet werden. Alles andere, einschließlich eines leeren Arrays, eines leeren Hash oder der Ganzzahl 0, wird als wahr ausgewertet.

Deshalb /foo/funktioniert das obige Beispiel und warum.

if "string" =~ /regex/

funktioniert wie erwartet und gibt nur dann den 'wahren' Teil des ifBlocks ein, wenn eine Übereinstimmung aufgetreten ist.

acib708
quelle
21

Eine prägnantere Redewendung als die oben akzeptierte Antwort, die in Rails (ab 3.1.0 und höher) verfügbar ist, lautet .in?:

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

Ich denke auch, dass es besser lesbar ist.

in?Weitere Informationen finden Sie in der Dokumentation.

Beachten Sie erneut, dass es nur in Rails und nicht in reinem Ruby verfügbar ist .

stwr667
quelle
2
Dies beruht auf Schienen, die OP bat um eine
Rubinlösung
2
Das ist richtig, obwohl ein erheblicher Teil der Ruby-Entwickler Rails verwendet, dachte ich, dass dies aufgrund seiner Klarheit und Kürze für einige eine bevorzugte Lösung sein könnte.
stwr667
1
Siehe stackoverflow.com/a/4239625/128421 . Es befindet sich in Rails, ist jedoch über die Active Support Core Extensions von Rails, mit denen kleine Gruppen von Methoden wie z. B. nur ausgewählt werden können, von Ruby aus leicht zugänglich in?.
Der Blechmann
Korrigieren Sie @theTinMan. "cde".in? my_stringin reinen Rubinausbeuten NoMethodError. Aber require 'active_support/core_ext/object/inclusion'damit funktioniert es, das entweder von Rails selbst oder von den reduzierten Active Support Core Extensions geladen werden kann .
stwr667
16

Ternärer Weg

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

ODER

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

Sie können die String Element Reference- Methode verwenden[]

In der []kann sich entweder ein Literal-Teilstring, ein Index oder ein Regex befinden:

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

Da dies nilfunktional dasselbe ist wie falseund jeder Teilstring, von dem zurückgegeben []wird true, können Sie die Logik so verwenden, als ob Sie die Methode verwenden .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" 

Stellen Sie nur sicher, dass Sie einen Index nicht mit einer Unterzeichenfolge verwechseln:

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

Sie können auch einen regulären Ausdruck verwenden:

> s[/A/i]
=> "a"
> s[/A/]
=> nil
dawg
quelle
2
Das ist phänomenal
Craig
3

Wie überprüfe ich, ob eine Zeichenfolge einen Teilstring in Ruby enthält?

Wenn Sie 'check' sagen, möchten Sie vermutlich einen Booleschen Wert zurückgeben. In diesem Fall können Sie ihn verwenden String#match?. match?Akzeptiert Zeichenfolgen oder reguläre Ausdrücke als ersten Parameter. Wenn dies der erstere ist, wird er automatisch in einen regulären Ausdruck konvertiert. Ihr Anwendungsfall wäre also:

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

String#match?hat den zusätzlichen Vorteil eines optionalen zweiten Arguments, das einen Index angibt, von dem aus die Zeichenfolge durchsucht werden soll. Standardmäßig ist dies auf eingestellt 0.

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

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

Auf diese Weise können Sie überprüfen, ob die Zeichenfolge Teilzeichenfolgen enthält oder nicht

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
quelle