2010-10-09 17 views
19

Jak mogę uzyskać wszystkie mecze w poniższym przykładzie:chciwy, dla Greedy, All-Greedy Matching w 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 .: Chcę mieć wszystkie mecze w ogólny sposób. Powyższy przykład jest tylko przykładem.

+1

Jaki jest twój przypadek użycia? Możemy udzielić ci lepszej porady z odrobiną więcej informacji. W tej chwili to zadanie wygląda bardzo dziwacznie i być może nierozsądnie. – user359996

+0

Witam user359996, dziękuję za twoje komentarze. Zgadzam się z tym, o czym wspomniałeś. Skontaktuję się z moim klientem, aby sprawdzić, czy jest to konieczne, czy nie. –

Odpowiedz

17

można użyć coś takiego:

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

Następnie powinieneś mieć trzy referencje zwrotne z ab, abc i abcd.

Ale, szczerze mówiąc, ten rodzaj wyrażeń regularnych nie ma zbytniego sensu, zwłaszcza gdy staje się większy, staje się nieczytelny.

Edit:

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

I masz błąd tam btw. To może tylko dopasować ab i abc (czytaj: ab + (nieobowiązkowo) charakter

Lazy wersja:

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

jest:

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

Cześć Tseng, Zgadzam się, że ten Regeks wygląda dziwnie, skontaktuję się z moim klientem, aby sprawdzić, czy naprawdę tego potrzebuje. –

+0

Rozmawiałem z moim klientem i powiedzieli, że to nie jest konieczne. Dzięki za odpowiedź. –

1

Nie można uzyskać trzech różnych wyników z tylko jednego meczu.

Jeśli chcesz dopasować tylko „AB” można użyć ab.? lub a.{1} (lub wiele innych opcji)
Jeśli chcesz dopasować tylko „abc” można użyć ab. lub a.{2} (lub wiele innych opcje)
Jeśli chcesz dopasować tylko „abcd” można użyć ab.* lub a.{3} (lub wiele innych opcji)

+0

Cześć Tahbaza i Colin Hebert, dziękuję za odpowiedź. ale zastanawiam się, czy istnieje ogólny sposób, nie tylko dla tego konkretnego przykładu. –

4

Jeśli rozwiązanie istnieje, to prawdopodobnie wiąże się z

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

wyjściowa::

grupę i wybrać opcję przechwytywania RightToLeft

Mówię "jeśli", ponieważ, podczas gdy działa dla twojego prostego testu, nie mogę zagwarantować, że ta sztuczka pomoże ci w problemach z rzeczywistego świata. Tryb RightToLeft jest jedną z bardziej innowacyjnych funkcji .NET - od ręki, nie mogę wymyślić innego smaku, który ma coś podobnego do niego. Oficjalna dokumentacja jest niewielka (delikatnie mówiąc) i jak dotąd nie ma wielu programistów, którzy go używają i dzielą się swoimi doświadczeniami w Internecie. Więc spróbuj i zobacz, co się stanie.