Ich muss mehrere Gruppen desselben Musters erfassen. Angenommen, ich habe eine folgende Zeichenfolge:
HELLO,THERE,WORLD
Und ich habe ein folgendes Muster geschrieben
^(?:([A-Z]+),?)+$
Ich möchte, dass jedes einzelne Wort erfasst wird, sodass Gruppe 1 lautet: "HALLO", Gruppe 2 ist "THERE" und Gruppe 3 ist "WORLD". Was meine Regex tatsächlich erfasst, ist nur das letzte, nämlich " WELT".
Ich teste meinen regulären Ausdruck hier und ich will , es benutzen mit Swift (vielleicht gibt es eine Möglichkeit , in Swift irgendwie Zwischenergebnisse zu bekommen, so dass ich sie nicht verwenden kann?)
UPDATE: Ich möchte nicht verwenden split
. Ich muss jetzt nur noch lernen, wie alle Gruppen erfasst werden, die dem Muster entsprechen, nicht nur die letzte.
,
?[A-Z]+
oder[^,]+
die Ergebnisse erfassenAntworten:
Mit einer Gruppe im Muster können Sie nur ein genaues Ergebnis in dieser Gruppe erhalten. Wenn Ihre Erfassungsgruppe durch das Muster wiederholt wird (Sie haben den
+
Quantifizierer für die umgebende nicht erfassende Gruppe verwendet), wird nur der letzte übereinstimmende Wert gespeichert.Sie müssen die Regex-Implementierungsfunktionen Ihrer Sprache verwenden, um alle Übereinstimmungen eines Musters zu finden. Dann müssten Sie die Anker und den Quantifizierer der nicht erfassenden Gruppe entfernen (und Sie könnten auch die nicht erfassende Gruppe selbst weglassen).
Erweitern Sie alternativ Ihren regulären Ausdruck und lassen Sie das Muster eine Erfassungsgruppe pro Gruppe enthalten, die Sie im Ergebnis erhalten möchten:
^([A-Z]+),([A-Z]+),([A-Z]+)$
quelle
Ich denke du brauchst so etwas ....
b="HELLO,THERE,WORLD" re.findall('[\w]+',b)
Welche in Python3 wird zurückkehren
['HELLO', 'THERE', 'WORLD']
quelle
Nur um ein zusätzliches Beispiel für Absatz 2 in der Antwort zu liefern. Ich bin mir nicht sicher, wie wichtig es für Sie ist, drei Gruppen in einem Spiel zu erhalten, anstatt drei Spiele mit einer Gruppe. ZB in groovig:
def subject = "HELLO,THERE,WORLD" def pat = "([A-Z]+)" def m = (subject =~ pat) m.eachWithIndex{ g,i -> println "Match #$i: ${g[1]}" } Match #0: HELLO Match #1: THERE Match #2: WORLD
quelle
Nachdem ich die Antwort von Byte Commander gelesen habe , möchte ich eine winzige mögliche Verbesserung vorstellen:
Sie können einen regulären Ausdruck generieren, der mit beiden
n
Wörtern übereinstimmt , solange Ihr Wortn
vorbestimmt ist. Wenn ich zum Beispiel zwischen 1 und 3 Wörtern abgleichen möchte, wird der reguläre Ausdruck:^([A-Z]+)(?:,([A-Z]+))?(?:,([A-Z]+))?$
wird die nächsten Sätze mit einer, zwei oder drei Erfassungsgruppen abgleichen.
HELLO,LITTLE,WORLD HELLO,WORLD HELLO
Sie können eine ausführliche Erklärung zu diesem regulären Ausdruck auf Regex101 sehen .
Wie gesagt, es ist ziemlich einfach, diesen regulären Ausdruck für alle Gruppen zu generieren, die Sie mit Ihrer Lieblingssprache verwenden möchten. Da ich kein besonders schneller Typ bin, hier ein Rubinbeispiel:
def make_regexp(group_regexp, count: 3, delimiter: ",") regexp_str = "^(#{group_regexp})" (count - 1).times.each do regexp_str += "(?:#{delimiter}(#{group_regexp}))?" end regexp_str += "$" return regexp_str end puts make_regexp("[A-Z]+")
Abgesehen davon würde ich vorschlagen, in diesem Fall keinen regulären Ausdruck zu verwenden. Es gibt viele andere großartige Tools, von einfachen
split
bis zu einigen Tokenisierungsmustern, je nach Ihren Anforderungen. IMHO, ein regulärer Ausdruck gehört nicht dazu. Zum Beispiel würde ich in Ruby so etwas wiestr.split(",")
oder verwendenstr.scan(/[A-Z]+/)
quelle
Sie haben tatsächlich eine Erfassungsgruppe, die mehrmals übereinstimmt. Nicht mehrere Erfassungsgruppen.
Javascript (js) -Lösung:
let string = "HI,THERE,TOM"; let myRegexp = /([A-Z]+),?/g; //modify as you like let match = myRegexp.exec(string); //js function, output described below while(match!=null){ //loops through matches console.log(match[1]); //do whatever you want with each match match = myRegexp.exec(bob); //find next match }
Ausgabe:
HI THERE TOM
Syntax:
// matched text: match[0] // match start: match.index // capturing group n: match[n]
Wie Sie sehen können, funktioniert dies für eine beliebige Anzahl von Übereinstimmungen.
quelle
Ich weiß, dass meine Antwort zu spät kam, aber es passiert mir heute und ich habe sie mit folgendem Ansatz gelöst:
^(([A-Z]+),)+([A-Z]+)$
Die erste Gruppe
(([A-Z]+),)+
stimmt also mit allen wiederholten Mustern überein, mit Ausnahme des letzten([A-Z]+)
, das mit dem letzten übereinstimmt. und dies wird dynamisch sein, egal wie viele wiederholte Gruppen in der Zeichenfolge.quelle