2011-09-23 6 views
5

Czy istnieje ograniczenie rozmiaru wyrażenia teoretycznego dla operatora "lub" w Regex.Replace , takie jak Regex.Replace ("abc", "(a | c | d | e ... dalej powiedz 500000 elementów tutaj) "," zzz ")?Czy istnieje ograniczenie rozmiaru wyrażenia teoretycznego dla operatora "lub" w Regex.Replace

Jakiekolwiek stackoverflowException na implementację .NET?

Dzięki

+2

Jeśli planujesz mieć wzór regex o długości 500000 elementów, możesz przemyśleć swoją architekturę rozwiązań. ;) –

+1

Masz na myśli teoretyczny limit, czy też masz praktyczny limit? – Chris

+0

@Chris both. Interesuje mnie także sytuacja, w której jest kompilowana, czyli. nowy Regex (wzór, RegexOptions.Compiled); – Bamboo

Odpowiedz

3

Nie ma limitu teoretyczne, choć każdy silnik wyrażenie regularne będzie miała swoje własne limity wdrożenia. W tym przypadku, ponieważ używasz .NET, limit wynika z ilości pamięci, z której może korzystać środowisko wykonawcze .NET.

Wyrażenie regularne z jednego miliona alernations działa dobrze dla mnie:

string input = "a<142>c"; 
var options = Enumerable.Range(0, 1000000).Select(x => "<" + x + ">"); 
string pattern = string.Join("|", options); 
string result = Regex.Replace(input, pattern, "zzz"); 

Wynik:

azzzc 

To bardzo powolna choć. Zwiększenie liczby opcji do 10 milionów daje mi OutOfMemoryException.

Prawdopodobnie skorzystaliby Państwo z innego podejścia.

+0

nowy Regex (wzór, RegexOptions.Compiled); Wydaje się, że jest OK, i nie ma żadnego wzrostu barana, dopóki nie pojawi się .Replace. Być może jest to wycofanie, które wykorzystuje potężny baran. dziękuję za poświęcony czas :) – Bamboo

2

Sposób działania wyrażeń regularnych oznacza, że ​​wymagania dotyczące pamięci i wydajności dla prostej ekspresji a|b|c.....|x|y|z zgodnie z opisem są niezłe, nawet w przypadku bardzo dużej liczby wariantów.

Jednak jeśli twoja ekspresja jest nawet nieco bardziej złożona, możesz spowodować, że wyrażenie straci wykładniczo swoją wydajność, a także znacznie zwiększyć jego pamięć, ponieważ wiele takich opcji może spowodować, że wykonywać masowe wycofywanie, jeśli inne części wyrażenia nie odpowiadają natychmiast.

Możesz zatem chcieć zachować ostrożność, robiąc takie rzeczy. Nawet jeśli teraz zadziała, wystarczy niewielka i względnie niewinna zmiana, aby wszystko się skończyło.

+0

Zmieniono, aby zmienić "backreferencing" na "backtracking", co moim zdaniem było tym, co miałeś na myśli. Backreferencje są czymś innym. Nie wahaj się cofnąć, jeśli faktycznie o nich mówisz. –

Powiązane problemy