2013-06-17 10 views
6

Quando il mio RegExp ha un numero di gruppi di acquisizione, voglio sapere quale gruppo ha effettuato l'acquisizione (o almeno il primo/ultimo gruppo di questo tipo, se ce ne fossero più di uno). Se hai familiarità con Python, questo è fondamentalmente l'equivalente di re.MatchObject.lastgroup. Alcuni codice per renderlo più chiaro:Trovare in modo efficiente il gruppo corrispondente in una ricerca 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)); 
} 

Esso stampa:

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

Gli spettacoli result matrice che i gruppi hanno fatto una cattura, ma non vedo alcun modo per trovare rapidamente fuori per ogni data partita, quale gruppo abbinato a senza iterare attraverso l'array. Ciò risulta utile nei casi in cui le regex di grandi dimensioni vengono create a livello di codice e l'iterazione è inefficiente.

Mi manca qualcosa di ovvio, o non è possibile?

+1

Non credo sia possibile. Ma cosa stai facendo esattamente quando questo diventa inefficiente? Potrebbe esserci una soluzione migliore rispetto alle regex di grandi dimensioni con grandi risultati. – Bergi

+0

@Bergi: re il mio uso, vedere il lungo commento che ho fatto alla risposta di minitech qui sotto. –

+0

So che questo è imbroglio, ma puoi usare 'indexOf' per evitare esplicitamente iteraring. Certo, il motore verrà iterato internamente – user123444555621

risposta

2

Non ti manca nulla; l'iterazione attraverso l'array è l'unico modo.

Quanti gruppi potrebbero esserci che l'iterazione attraverso le partite è in realtà un problema di prestazioni? Se non hai bisogno di un gruppo, puoi sempre renderlo non-catturante, ma ...

+0

Grazie per la risposta. Re performance: ho un caso d'uso in cui creo una regex piuttosto lunga con dozzine di gruppi. Poiché questa parte del codice è sensibile alle prestazioni, è un peccato dover iterare su un array per ogni singola corrispondenza. Se sei davvero curioso, vedi: https://gist.github.com/eliben/5797351 - è un lexer basato su espressioni regolari, e infila tutto in un'unica enigmatica regex. Utilizza anche i gruppi con nome, ma non è necessario. Sapere quale gruppo corrisponde * è *, però. –

+0

@EliBendersky: è possibile creare un'espressione regolare diversa per ciascuna e controllare se ciascuna corrisponde ogni volta. Non penso che sarebbe più veloce, comunque. Di solito analizzo le cose "manualmente" in JavaScript, ma questo non funziona se stai cercando di renderlo generico, eh? = P – Ryan

+0

+1, probabilmente avrei usato più regex qui. Mi chiedo se questo compito (non il tuo, quello di OP) possa essere diviso ancora meglio, raccogliendo tutti i token di qualche categoria alla prima esecuzione, poi raccogliendo tutti gli altri in seguito. – raina77ow

Problemi correlati