2013-06-17 13 views
6

Gdy moja RegExp ma wiele grup przechwytywania, chcę wiedzieć, która grupa wykonała przechwytywanie (lub co najmniej pierwszą/ostatnią taką grupę, jeśli było więcej niż jedno). Jeśli znasz Python, jest to w zasadzie odpowiednik re.MatchObject.lastgroup. Niektóre kodu do uczynienia go bardziej zrozumiałym:Skutecznie znajdź grupę, która została dopasowana w wyszukiwaniu RegExp

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)); 
} 

Drukuje:

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' ] 

pokazach result tablic, które grupy skierowane do schwytania, ale nie widzę sposobu, aby szybko znaleźć dla każdego danego meczu, który grupowej dopasowany bez iteracji przez macierz. Przydaje się to w przypadkach, gdy duże regexy są programowane programowo, a iteracja jest nieefektywna.

Czy brakuje mi czegoś oczywistego, czy nie jest to możliwe?

+1

Nie sądzę, że to możliwe. Ale co dokładnie robisz, gdy staje się to nieefektywne? Może istnieć lepsze rozwiązanie niż duże wyrażenia regularne z dużymi wynikami. – Bergi

+0

@Bergi: Ponownie używam, zobacz długotrwały komentarz do odpowiedzi minitech poniżej. –

+0

Wiem, że to oszustwo, ale możesz użyć 'indexOf', aby uniknąć jawnego powtarzania. Oczywiście, silnik będzie iterować wewnętrznie – user123444555621

Odpowiedz

2

Nie brakuje niczego; iterowanie przez macierz jest jedynym sposobem.

Ile grup może być, że iteracja przez mecze jest w rzeczywistości problemem z wydajnością? Jeśli nie potrzebujesz grupy, zawsze możesz ją przechwycić, ale ...

+0

Dzięki za odpowiedź. Re wydajność: Mam przypadek użycia, w którym tworzę dość długie wyrażenie regularne z dziesiątkami grup. Ponieważ ta część kodu jest wrażliwa na wydajność, wstydem jest powtarzanie tablicy dla każdego pojedynczego pojedynku. Jeśli jesteś naprawdę ciekawy zobacz - https://gist.github.com/eliben/5797351 - jest to lexer oparty na regexie, który umieszcza wszystko w jednym ogromnym wyrażeniu regularnym. Używa również nazwanych grup, ale nie jest to konieczne. Wiedząc, która grupa była zgodna * jest *. –

+0

@EliBendersky: Możesz utworzyć inne wyrażenie regularne dla każdego i sprawdzić, czy każdy pasuje za każdym razem. Nie sądzę, że byłoby to jeszcze szybsze. Zwykle parsuję rzeczy "ręcznie" w JavaScript, ale to nie działa, jeśli próbujesz zrobić to generycznie, co? = P – Ryan

+0

+1, prawdopodobnie użyłbym wielu wyrażeń regularnych tutaj. Zastanawiam się, czy to zadanie (nie twoje, jedno z OP) można podzielić jeszcze lepiej, zbierając wszystkie żetony jakiejś kategorii na początku, a potem zbierając wszystkie pozostałe. – raina77ow

Powiązane problemy