Suche…


Gruppen, benannt und anders.

Ruby erweitert die Standardgruppensyntax (...) um eine benannte Gruppe (?<name>...) . Dies ermöglicht das Extrahieren nach Namen, anstatt zu zählen, wie viele Gruppen Sie haben.

name_reg = /h(i|ello), my name is (?<name>.*)/i #i means case insensitive

name_input = "Hi, my name is Zaphod Beeblebrox"

match_data = name_reg.match(name_input) #returns either a MatchData object or nil
match_data = name_input.match(name_reg) #works either way

if match_data.nil? #Always check for nil! Common error.
  puts "No match"
else
  match[0] #=> "Hi, my name is Zaphod Beeblebrox"
  match[1] #=> "i" #the first group, (i|ello)
  match[2] #=> "Zaphod Beeblebrox"
  #Because it was a named group, we can get it by name
  match[:name]  #=> "Zaphod Beeblebrox"
  match["name"] #=> "Zaphod Beeblebrox"
  puts "Hello #{match[:name]}!"
end

Der Index der Übereinstimmung wird basierend auf der Reihenfolge der linken Klammern gezählt (wobei der gesamte reguläre Ausdruck die erste Gruppe bei Index 0 ist).

reg = /(((a)b)c)(d)/
match = reg.match 'abcd'
match[0] #=> "abcd"
match[1] #=> "abc"
match[2] #=> "ab"
match[3] #=> "a"
match[4] #=> "d"

= ~ Operator

if /hay/ =~ 'haystack'
  puts "There is hay in the word haystack"
end

Hinweis: Die Reihenfolge ist signifikant . Obwohl 'haystack' =~ /hay/ in den meisten Fällen gleichwertig ist, können die Nebenwirkungen unterschiedlich sein:

  • Von benannten Erfassungsgruppen erfasste Zeichenfolgen werden lokalen Variablen nur zugewiesen, wenn Regexp#=~ aufgerufen wird ( regexp =~ str );
  • Da der rechte Operand möglicherweise ein beliebiges Objekt ist, wird für regexp =~ str entweder Regexp#=~ oder String#=~ aufgerufen.

Beachten Sie, dass dies keinen True / False-Wert zurückgibt. Stattdessen wird entweder der Index der Übereinstimmung zurückgegeben, wenn er gefunden wird, oder Null, wenn er nicht gefunden wird. Da alle ganzen Zahlen in Rubin wahr sind (einschließlich 0) und Null falsch ist, funktioniert dies. Wenn Sie einen booleschen Wert wünschen, verwenden Sie #=== wie in einem anderen Beispiel gezeigt .

Quantifizierer

Mit Quantifizierern können Sie die Anzahl der wiederholten Zeichenfolgen angeben.

  • Null oder eins:

    /a?/
    
  • Null oder viele:

    /a*/
    
  • Eins oder viele:

    /a+/
    
  • Genaue Anzahl:

    /a{2,4}/ # Two, three or four
    /a{2,}/  # Two or more
    /a{,4}/  # Less than four (including zero)
    

Quantifizierer sind standardmäßig gierig , was bedeutet, dass sie so viele Zeichen wie möglich benötigen, während sie trotzdem eine Übereinstimmung herstellen. Normalerweise fällt das nicht auf:

/(?<site>.*) Stack Exchange/ =~ 'Motor Vehicle Maintenance & Repair Stack Exchange'

Der angegebene site der Erfassungsgruppe wird wie erwartet auf "Kfz-Wartung und Reparatur" gesetzt. Wenn 'Stack Exchange' jedoch ein optionaler Teil der Zeichenfolge ist (da dies stattdessen 'Stack Overflow' sein könnte), funktioniert die naive Lösung nicht wie erwartet:

/(?<site>.*)( Stack Exchange)?/

Diese Version stimmt immer noch überein, aber das benannte Capture enthält "Stack Exchange", da * diese Charaktere gierig frisst. Die Lösung besteht darin, ein weiteres Fragezeichen hinzuzufügen, um das * faul zu machen:

/(?<site>.*?)( Stack Exchange)?/

Anhängen ? zu jedem Quantifizierer wird es faul machen.

Charakterklassen

Beschreibt Bereiche von Symbolen

Sie können Symbole explizit auflisten

/[abc]/ # 'a' or 'b' or 'c'

Oder verwenden Sie Bereiche

/[a-z]/ # from 'a' to 'z'

Es ist möglich, Bereiche und einzelne Symbole zu kombinieren

/[a-cz]/ # 'a' or 'b' or 'c' or 'z'

Führender Bindestrich ( - ) wird als Zeichen behandelt

/[-a-c]/ # '-' or 'a' or 'b' or 'c'

Klassen können negativ sein, wenn Symbole mit ^ vorangestellt werden

/[^a-c]/ # Not 'a', 'b' or 'c'

Es gibt einige Abkürzungen für weit verbreitete Klassen und spezielle Charaktere sowie Leitungsenden

^  # Start of line
$  # End of line
\A # Start of string
\Z # End of string, excluding any new line at the end of string
\z # End of string
.  # Any single character
\s # Any whitespace character
\S # Any non-whitespace character
\d # Any digit
\D # Any non-digit
\w # Any word character (letter, number, underscore)
\W # Any non-word character
\b # Any word boundary

\n wird einfach als neue Zeile verstanden

Um einem reservierten Zeichen zu entkommen, wie / oder [] und anderen, verwenden Sie den Backslash (linker Schrägstrich)

\\ # => \
\[\] # => []

Reguläre Ausdrücke in Case Statements

Sie können mit einer switch-Anweisung testen, ob eine Zeichenfolge mit mehreren regulären Ausdrücken übereinstimmt.

Beispiel

case "Ruby is #1!"
when /\APython/
    puts "Boooo."
when /\ARuby/
    puts "You are right."
else 
    puts "Sorry, I didn't understand that."
end

Dies funktioniert, weil case-Anweisungen mit dem Operator === auf Gleichheit === werden, nicht mit dem Operator == . Wenn sich ein Regex mit === auf der linken Seite eines Vergleichs befindet, === er eine Zeichenfolge, um zu sehen, ob sie übereinstimmt.

Regexp definieren

Ein Regexp kann auf drei verschiedene Arten in Ruby erstellt werden.

  • Schrägstriche verwenden: / /

  • mit %r{}

  • mit Regex.new

    #The following forms are equivalent
    regexp_slash = /hello/
    regexp_bracket = %r{hello}
    regexp_new = Regexp.new('hello')
    
    string_to_match = "hello world!"
    
    #All of these will return a truthy value
    string_to_match =~ regexp_slash    # => 0
    string_to_match =~ regexp_bracket  # => 0
    string_to_match =~ regexp_new      # => 0
    

Spiel? - Boolesches Ergebnis

Gibt " true oder " false Dies gibt an, ob der reguläre Ausdruck übereinstimmt oder nicht, ohne $~ und andere verwandte Variablen zu aktualisieren. Wenn der zweite Parameter vorhanden ist, gibt er die Position in der Zeichenfolge an, um die Suche zu beginnen.

/R.../.match?("Ruby")    #=> true
/R.../.match?("Ruby", 1) #=> false
/P.../.match?("Ruby")    #=> false

Ruby 2.4+

Allgemeine schnelle Verwendung

Reguläre Ausdrücke werden in Methoden häufig als Parameter verwendet, um zu überprüfen, ob andere Zeichenfolgen vorhanden sind, oder um Zeichenfolgen zu suchen und / oder zu ersetzen.

Sie werden oft folgendes sehen:

string = "My not so long string"
string[/so/] # gives so
string[/present/] # gives nil
string[/present/].nil? # gives true

Sie können dies also einfach als Überprüfung verwenden, ob eine Zeichenfolge eine Teilzeichenfolge enthält

puts "found" if string[/so/]

Fortgeschrittener, aber immer noch kurz und schnell: Suchen Sie mithilfe des zweiten Parameters nach einer bestimmten Gruppe. In diesem Beispiel ist 2 der zweite, da die Nummerierung bei 1 und nicht bei 0 beginnt. Eine Gruppe ist das, was in Klammern steht.

string[/(n.t).+(l.ng)/, 2] # gives long

Wird auch häufig verwendet: Suchen und Ersetzen mit sub oder gsub , \1 ergibt die erste gefundene Gruppe, \2 die zweite:

string.gsub(/(n.t).+(l.ng)/, '\1 very \2') # My not very long string

Das letzte Ergebnis wird gespeichert und kann in den folgenden Zeilen verwendet werden

$2 # gives long


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow