2010-02-12 9 views
6

Sto facendo una piccola applicazione usando i tipi .NET Regex. E i tipi "Cattura, Raggruppa e Abbina" mi hanno totalmente confuso. Non ho mai visto una soluzione così brutta. Qualcuno potrebbe spiegare il loro utilizzo per me? Grazie molto.Differenze tra .NET Capture, Group, Match

+0

Hai un'espressione regolare di esempio che vuoi che spieghiamo? – Gumbo

risposta

12

Ecco un esempio più semplice di quello nel documento @Dav citati:

string s0 = @"foo%123%456%789"; 
Regex r0 = new Regex(@"^([a-z]+)(?:%([0-9]+))+$"); 
Match m0 = r0.Match(s0); 
if (m0.Success) 
{ 
    Console.WriteLine(@"full match: {0}", m0.Value); 
    Console.WriteLine(@"group #1: {0}", m0.Groups[1].Value); 
    Console.WriteLine(@"group #2: {0}", m0.Groups[2].Value); 
    Console.WriteLine(@"group #2 captures: {0}, {1}, {2}", 
        m0.Groups[2].Captures[0].Value, 
        m0.Groups[2].Captures[1].Value, 
        m0.Groups[2].Captures[2].Value); 
} 

risultato:

full match: foo%123%456%789
group #1: foo
group #2: 789
group #2 captures: 123, 456, 789

I risultati full match e group #1 sono semplici, ma gli altri richiedono qualche spiegazione. Il gruppo n. 2, come puoi vedere, si trova all'interno di un gruppo non acquisibile controllato da un quantificatore +. Corrisponde a tre volte, ma se si richiede il suo Value, si ottiene solo ciò che corrisponde alla terza volta - l'acquisizione finale. Allo stesso modo, se si utilizza il segnaposto $2 in una stringa di sostituzione, l'acquisizione finale viene inserita al suo posto.

Nella maggior parte delle espressioni regex, è tutto ciò che è possibile ottenere; ogni acquisizione intermedia viene sovrascritta dalla successiva e persa; .NET è quasi unico nel preservare tutte le acquisizioni e renderle disponibili dopo l'esecuzione della partita. Puoi accedervi direttamente come ho fatto qui o scorrere lo CaptureCollection come se fosse un MatchCollection. Però non esistono equivalenti per i segnaposti di stringa di sostituzione dello stile $1.

Quindi il motivo per cui il design dell'API è così brutto (come lo si è detto) è duplice: in primo luogo è stato adattato dal supporto regex integrale di Perl al framework orientato agli oggetti di .NET; quindi la struttura CaptureCollection è stata innestata su di essa. Perl 6 offre una soluzione molto più pulita, ma gli autori lo hanno fatto riscrivendo Perl praticamente da zero e lanciando la compatibilità con le versioni precedenti.

+1

Ciao, grazie Alan. Solo altre 2 domande, ci sono una proprietà denominata "Cattura" per entrambe le partite e il gruppo, qual è la differenza tra Match.Captures e Group.Captures? E perché Match.Groups [0] è sempre uguale a Match.Value? Grazie ancora. – smwikipedia

+0

A Match ISA Group ISA Capture, quindi Match eredita 'Cattura' da Gruppo e' Valore' da Capture. Il Match è il gruppo zero'th, quindi 'Match.Captures' è semplicemente un elenco di un elemento che contiene l'intero match - come se avessimo bisogno di * un altro * modo per riferirsi ad esso! 'Value' è ovviamente il modo preferito, essendo molto più breve e più intuitivo. Ma anche questo è opzionale se si utilizza il riferimento Match/Group/Capture che si aspetta una stringa, perché 'ToString()' si limita a delegare a 'Value'. –

+0

Per quanto riguarda * perché * il Match è il gruppo zero'th, vedere questa risposta: http://stackoverflow.com/questions/2248213/in-c-regular-expression-why-does-the-initial-match-show -up-in-the-groups/2248767 # 2248767 –

2

Una corrispondenza è il risultato di una singola partita della insieme di un'espressione regolare.. Gruppi e Cattura hanno entrambi qualcosa da fare con i gruppi di cattura (ogni (expression) all'interno della regex), ma variano nel modo in cui si comportano. Ecco una citazione dal l'articolo di MSDN sulla classe Capture che spiega la differenza:

Se non si applicano un quantificatore a un gruppo cattura, i Group.Captures proprietà restituisce un CaptureCollection con un unico oggetto di acquisizione che fornisce informazioni sulla stessa acquisizione come oggetto Gruppo. Se applicare un quantificatore a un gruppo di cattura, il Group.Index, Group.Length, e le proprietà Group.Value fornire informazioni solo l'ultimo gruppo acquisito, mentre la cattura oggetti nel CaptureCollection fornire informazioni su tutte le acquisizioni di subexpression . L'esempio fornisce un'illustrazione.

(Source)

Problemi correlati