Sie benötigen die Regexp#match
Methode. Wenn Sie /\[(.*?)\](.*)/.match('[ruby] regex')
schreiben, wird ein Objekt MatchData
zurückgegeben. Wenn wir das Objekt matches
nennen, dann unter anderem:
matches[0]
gibt die ganze abgestimmte String.
matches[n]
gibt die n-te Erfassungsgruppe zurück ($n
).
matches.to_a
gibt ein Array bestehend aus matches[0]
bis matches[N]
zurück.
matches.captures
gibt ein Array zurück, das nur aus der einfangenden Gruppe besteht (matches[1]
bis matches[N]
).
matches.pre_match
gibt alles vor der übereinstimmenden Zeichenfolge zurück.
matches.post_match
gibt alles nach der übereinstimmenden Zeichenfolge zurück.
Es gibt mehr Methoden, die anderen speziellen Variablen entsprechen, usw .; Sie können überprüfen, MatchData
's docs für mehr. Somit wird in diesem speziellen Fall alles, was Sie schreiben müssen, ist
tag, keyword = /\[(.*?)\](.*)/.match('[ruby] regex').captures
Edit 1: Okay, für die schwierigere Aufgabe, wirst du stattdessen die String#scan
Methode wollen, die @Theo verwendet; Wir werden jedoch eine andere Regex verwenden. Der folgende Code sollte funktionieren:
# You could inline the regex, but comments would probably be nice.
tag_and_text =/\[([^\]]*)\] # Match a bracket-delimited tag,
\s* # ignore spaces,
([^\[]*) /x # and match non-tag search text.
input = '[ruby] [regex] [rails] one line [foo] [bar] baz'
tags, texts = input.scan(tag_and_text).transpose
Die input.scan(tag_and_text)
wird eine Liste von Tag-Suche Textpaare zurück:
[ ["ruby", ""], ["regex", ""], ["rails", "one line "]
, ["foo", ""], ["bar", "baz"] ]
Der transpose
Anruf klappt das, so dass Sie ein Paar, bestehend aus einem Tag Liste und eine Suchtextliste:
[["ruby", "regex", "rails", "foo", "bar"], ["", "", "one line ", "", "baz"]]
Sie können dann tun, was Sie wollen, mit den Ergebnissen. Ich könnte darauf hindeuten, zum Beispiel
search_str = texts.join(' ').strip.gsub(/\s+/, ' ')
Dies wird die Suche Schnipsel mit einzelnen Leerzeichen verketten, loszuwerden führenden und nachfolgenden Leerzeichen und ersetzen Läufe mehrerer Räume mit einem einzigen Raum.
Für das Update: Wenn Sie dies in einem einzigen regulären Ausdruck tun möchten, benötigen Sie die .NET oder Perl 6 Regex-Engine, derzeit die einzigen, die Captures innerhalb wiederholter Elemente unterstützen. Mit IronRuby haben Sie wahrscheinlich eine Chance. Siehe auch http://stackoverflow.com/questions/2652554/which-regex-flavors-support-captures-aso-opped-to-capturing-groups - aus Gründen der Lesbarkeit und Wartbarkeit ist jedoch ein zweistufiger Ansatz wahrscheinlich sinnvoller . –