2013-06-17 14 views
6

Wenn meine RegExp eine Reihe von einfangenden Gruppen hat, möchte ich wissen, welche Gruppe die Erfassung (oder zumindest die erste/letzte solche Gruppe, wenn es mehrere waren) gemacht. Wenn Sie mit Python vertraut sind, entspricht dies im Wesentlichen dem re.MatchObject.lastgroup. Einige Code, um es deutlicher:Effizient finden, welche Gruppe in einer RegExp Suche übereinstimmt

var re_captures = new RegExp("(\\d+)|(for)|(\\w+)", "g"); 
var str = " for me 20 boxes please"; 
var result; 

while ((result = re_captures.exec(str)) !== null) { 
    console.log(result[0], 'at', result.index, result.slice(1)); 
} 

Er druckt:

for at 1 [ undefined, 'for', undefined ] 
me at 5 [ undefined, undefined, 'me' ] 
20 at 8 [ '20', undefined, undefined ] 
boxes at 11 [ undefined, undefined, 'boxes' ] 
please at 17 [ undefined, undefined, 'please' ] 

Die result Array zeigt, welche Gruppen eine Aufnahme gemacht, aber ich sehe keine Möglichkeit, schnell für jede gegebene Spiel, um herauszufinden, welche Gruppe übereinstimmte ohne durch das Array zu durchlaufen. Dies ist nützlich in Fällen, in denen große Regexes programmatisch erstellt werden und das Iterieren ineffizient ist.

Fehle ich etwas offensichtlich, oder ist es nicht möglich?

+1

Ich glaube nicht, dass es möglich ist. Aber was genau machst du, wenn das ineffizient wird? Es könnte eine bessere Lösung geben als große Regexes mit großen Ergebnissen. – Bergi

+0

@Bergi: re meine Verwendung, sehen Sie den länglichen Kommentar, den ich zu Minitechs Antwort unten gemacht habe. –

+0

Ich weiß, das ist Betrug, aber Sie können 'indexOf' verwenden, um Iteraring explizit zu vermeiden. Sicher, die Engine wird intern iterieren – user123444555621

Antwort

2

Sie verpassen nichts; das Iterieren durch das Array ist der einzige Weg.

Wie viele Gruppen könnte es geben, dass das Durchlaufen der Matches tatsächlich ein Performance-Problem ist? Wenn Sie keine Gruppe brauchen, können Sie immer nicht erfassen, aber ...

+0

Danke für die Antwort. Re-Performance: Ich habe einen Anwendungsfall, in dem ich einen ziemlich langen Regex mit Dutzenden von Gruppen erstellen kann. Da dieser Teil des Codes leistungsabhängig ist, ist es eine Schande, für jedes einzelne Match über ein Array zu iterieren. Wenn Sie wirklich neugierig sind, sehen Sie - https://gist.github.com/eliben/5797351 - es ist ein Regex-basierter Lexer, und es steckt alles in einen riesigen Regex. Es verwendet auch benannte Gruppen, aber das ist nicht notwendig. Zu wissen, welche Gruppe mit * übereinstimmt, ist *. –

+0

@EliBendersky: Sie könnten für jeden einzelnen einen anderen regulären Ausdruck erstellen und prüfen, ob jeder für jedes Mal übereinstimmt. Ich denke nicht, dass es schneller wäre. Ich pars normalerweise Sachen "manuell" in JavaScript, aber das funktioniert nicht, wenn Sie versuchen, es generisch zu machen, nicht wahr? = P – Ryan

+0

+1, ich hätte hier wahrscheinlich mehrere Regexes benutzt. Ich frage mich, ob das (nicht deine, die von OP) Aufgabe noch besser aufgeteilt werden kann, sammle alle Token einer Kategorie auf Anhieb und sammle danach alle anderen ein. – raina77ow

Verwandte Themen