2010-10-09 14 views
19

Come posso ottenere tutte le partite nel seguente esempio:Greedy, non avido, All-Greedy corrispondenza in C# Regex

// Only "abcd" is matched 
MatchCollection greedyMatches = Regex.Matches("abcd", @"ab.*"); 

// Only "ab" is matched 
MatchCollection lazyMatches = Regex.Matches("abcd", @"ab.*?"); 

// How can I get all matches: "ab", "abc", "abcd" 

P.S .: voglio avere le tutte le partite in modo generico. L'esempio sopra è solo un esempio.

+1

Qual è il tuo caso d'uso? Possiamo darti consigli migliori con un po 'più di informazioni. In questo momento, questo compito sembra molto bizzarro e forse sconsiderato. – user359996

+0

Ciao utente359996, grazie per i vostri commenti. Sono d'accordo con quello che hai menzionato. Contatterò il mio cliente per vedere se è necessario o meno. –

risposta

17

si potrebbe usare qualcosa di simile:

MatchCollection nonGreedyMatches = Regex.Matches("abcd", @"(((ab)c)d)"); 

Quindi dovresti avere tre backriver con ab, abc e abcd.

Ma, ad essere onesti, questo tipo di regex non ha molto senso, soprattutto quando diventa più grande diventa illeggibile.

Edit:

MatchCollection nonGreedyMatches = Regex.Matches("abcd", @"ab.?"); 

E hai un errore ci btw. Questo può abbinare solo ab e abc (leggi: ab + qualsiasi carattere (opzionale)

versione pigro di:

MatchCollection greedyMatches = Regex.Matches("abcd", @"ab.*"); 

è:

MatchCollection nonGreedyMatches = Regex.Matches("abcd", @"ab.*?"); 
+0

Ciao Tseng, sono d'accordo che questo RegEx sembra strano, contatterò il mio cliente per verificare se ne ha davvero bisogno. –

+0

Ho discusso con il mio cliente e hanno detto che non è necessario. Grazie per la tua risposta. –

1

Non è possibile ottenere tre risultati diversi da una sola partita.

Se si desidera far corrispondere solo "ab" è possibile utilizzare ab.? o a.{1} (o un sacco di altre opzioni)
Se si desidera far corrispondere solo "abc" è possibile utilizzare ab. o a.{2} (o un sacco di altri opzioni)
Se si desidera far corrispondere solo "ABCD" è possibile utilizzare ab.* o a.{3} (o un sacco di altre opzioni)

+0

Ciao Tahbaza e Colin Hebert, grazie per la tua risposta. ma mi chiedo se c'è un modo generico, non solo per questo specifico esempio. –

4

Se esiste una soluzione, probabilmente comporta un gruppo di cattura e l'opzione RightToLeft:

string s = @"abcd"; 
Regex r = new Regex(@"(?<=^(ab.*)).*?", RegexOptions.RightToLeft); 
foreach (Match m in r.Matches(s)) 
{ 
    Console.WriteLine(m.Groups[1].Value); 
} 

uscita:

Dico "se" perché, mentre funziona per il tuo semplice caso di test, non posso garantire che questo trucco possa aiutarti con il tuo problema nel mondo reale. La modalità RightToLeft è una delle funzionalità più innovative di .NET - a mano a mano, non riesco a pensare ad un altro sapore che abbia qualcosa di equivalente ad esso. La documentazione ufficiale su di essa è scarna (per usare un eufemismo), e finora non sembrano esserci molti sviluppatori che lo usano e condividono le loro esperienze online. Quindi provalo e guarda cosa succede.