2013-07-29 24 views
5

Ho appena fatto i cruciverba regex divertenti a http://regexcrossword.com/ - e ho scoperto che non capisco cosa significhi gruppi quantificatori, ad es. (.) (.) + O *Regex, gruppo e quantificatore

mi permetta di provare a http://ole.michelsen.dk/tools/regex.html, offre il JavaScript e il motore PHP espressione regolare: "Trololo"

La stringa da abbinare contro è (senza virgolette). (Se il passaggio sul "match Globale" cambiato qualcosa, viene aggiunto come la versione con mano di fondo, vale a dire JS', in quanto non ha cambiato nulla nel modo di PHP.)

JS, (.)+ => 0: Trololo! 1: ! 
JS', (.)+ => 0: Trololo! 
PHP, (.)+ => 0: Trololo! 0: ! 
JS, (.)* => 0: Trololo! 1: ! 
JS', (.)* => 0: Trololo! 
PHP, (.)* => 0: Trololo! 1: 0: ! 1: 
JS, (.){5} => 0: Trolo 1: o 
JS', (.){5} => 0: Trolo 
PHP, (.){5} => 0: Trolo 0: o 
JS, (.){4} => 0: Trol 1: l 
JS', (.){4} => 0: Trol 1: olo! 
PHP, (.){4} => 0: Trol 1: olo! 0: l 1: ! 

C'è qualche risposta normativa ciò che il la semantica di questo è?

+0

Cosa sono 'JS' e' JS''? Qual è la differenza? –

+1

Penso che il sito non ti sta dando gruppi corretti. Utilizzare invece http://www.regexplanet.com/. –

risposta

3

Le uscite non sono etichettate correttamente, questo è tutto.

Prima di tutto, cosa deve essere ? Se si ripete un gruppo, ogni nuova istanza sovrascrive l'ultima cattura. Se il gruppo non viene utilizzato, restituirà una stringa vuota o qualcosa come undefined in JS (dipende dal sapore). C'è un buon articolo su regular-expressions.info sull'argomento.

Ora come si arriva ai risultati? Iniziamo con JavaScript.

Tutti gli esempi contrassegnati con JS (quelli non globali) corrispondono alla descrizione precedente. Corrispondono alla quantità di caratteri desiderata in 0 e acquisiscono l'ultimo carattere in 1. Quindi possiamo ignorarli.

Che dire di quelli globali? Qui l'output è stato interpretato in modo errato. Quando si utilizza la bandiera globale con la funzione String.match(), non si ottiene più una matrice di tutte le acquisizioni, ma solo una matrice di tutte le corrispondenze (gruppo 0 per ciascuna corrispondenza). Quindi, nel caso di +, * e {5} dove c'è una sola corrispondenza, si ottiene solo quell'unico risultato. Con {4} c'è spazio sufficiente per due corrispondenze nella stringa di destinazione, quindi l'array risultante contiene due elementi. Per ottenere tutte le acquisizioni con la bandiera globale, dovrai scrivere un ciclo e usare invece RegExp.exec() (che ti dà una corrispondenza alla volta, ma tutte le sue acquisizioni).

E che cos'è il PHP? Sembra che stia usando preg_match_all, che è comunque globale, ed è per questo che l'uso di g non ha avuto alcun effetto. Il + fornisce il risultato che ci si aspetta di nuovo. Così fa {5}.

Cosa sono gli altri due? Qui, l'output è stato interpretato nel modo sbagliato. Per impostazione predefinita, preg_match_all fornisce una matrice bidimensionale, in cui il primo indice corrisponde al gruppo e il secondo corrisponde alla corrispondenza. Nel tuo output, viene interpretato al contrario. Quindi, quando ci sono più corrispondenze, la prima coppia di 0 e 1 corrisponde all'intera corrispondenza di due corrispondenze trovate. La seconda coppia 0 e 1 è ciò che hai catturato in queste due partite.

Quindi per *, si ottiene per prima cosa la stringa intera come corrispondenza e l'ultimo carattere come cattura (le due cose contrassegnate con 0), che è corretto. E poi, dal momento che * consente corrispondenze a larghezza zero, si ottiene un'altra corrispondenza (vuota) alla fine della stringa, insieme a un'acquisizione vuota.Non sono sicuro del motivo per cui l'esempio JS' corrispondente non contenga una stringa vuota aggiuntiva, tuttavia, poiché String.match farebbe la stessa cosa.

E per {4}, basta avere due partite (Trol e olo!) come nel caso JavaScript con la cattura rispettivamente l e !, ancora una volta, che è perfettamente bene.

+0

> Prima di tutto, cosa dovrebbe accadere? Esattamente, questa è la domanda :-) In realtà mi aspettavo, che la corrispondenza (.) * Su abcd avrebbe dato 0. abcd 1. a 2. b 3. c 4. d - cioè, ottengo più gruppi, come il quantificatore sembra quantificare il gruppo. Ma pensarci più a lungo, non sembra affatto utilizzabile, poiché i riferimenti di gruppo sono fissi. – Falko

+1

@Falko, l'unico sapore regex che lo rende .NET. Lì si ottiene un oggetto Gruppo per ogni gruppo che contiene una raccolta di Cattura. –

+0

Ah, fantastico. Ma come detto, non riesco a immaginare come possa essere utile in pratica. – Falko