2009-08-09 12 views
15

Po przeczytaniu całkiem niezłej article o optymalizacji regex w java zastanawiałem się, jakie są inne dobre wskazówki do tworzenia szybkich i wydajnych wyrażeń regularnych?Regex Performance Optimization Porady i wskazówki

+0

chciałbym wspomnieć [Boolean Sequence] (https://github.com/NaturalIntelligence/BooleanSequence), który obecnie obsługuje mniej symboli RE, ale są one szybkie i elastyczne oraz pełne wielu przydatnych funkcji. Możesz pisać własne szablony, aby dodać więcej funkcji lub przyspieszyć je. Przeprowadzają także automatyczną optymalizację i można zobaczyć, jak są oceniane za pomocą wykresów opartych na json lub json. –

Odpowiedz

7

pomocą dowolnego (kropka) operator oszczędnie, jeśli można zrobić to w inny sposób, zrób to, kropka będzie zawsze cię ugryźć ...

nie jestem pewien, czy jest PCRE NFA i jestem znane tylko z PCRE, ale + i * są zwykle chciwe domyślnie, będą pasować tak dużo, jak to możliwe, aby zmienić to wokół użycia +? i *? Aby dopasować to, co najmniej możliwe, pamiętaj o tych dwóch klauzulach podczas pisania wyrażeń regularnych.

3

Należy wiedzieć, kiedy nie używać do używania wyrażenia regularnego - czasami rozwiązanie kodowane ręcznie jest bardziej wydajne i bardziej zrozumiałe.

Przykład: załóżmy, że chcesz dopasować liczbę całkowitą, która jest równomiernie podzielna przez 3. Łatwo jest zaprojektować skończoną maszynę stanów, aby to osiągnąć, a zatem musi istnieć odpowiednie wyrażenie regularne, ale wypisanie go nie jest tak banalne - i Na pewno nie znoszę tego debugowania!

+1

Tak ... ale w niektórych systemach numerycznych jest to banalne. :-P –

+9

masz na myśli to: '(((0 | 3 | 6 | 9) | ((1 | 4 | 7) (0 | 3 | 6 | 9) * (2 | 5 | 8))) | (((2 | 5 | 8) | ((1 | 4 | 7) (0 | 3 | 6 | 9) * (1 | 4 | 7))) ((0 | 3 | 6 | 9) | ((2 | 5 | 8) (0 | 3 | 6 | 9) * (1 | 4 | 7))) * ((1 | 4 | 7) | ((2 | 5 | 8) (0 | 3 | 6 | 9) * (2 | 5 | 8)))) * '? (Tak, zrobiłem DFA, a następnie GNFA, a następnie wyreguję: p) –

+1

Użyj szybkiej implementacji, gdy nie masz żadnych odsyłaczy wstecz. https://swtch.com/~rsc/regexp/regexp1.html – clemens

27
  1. Użyj grupa non-przechwytywanie (?:pattern) kiedy trzeba powtarzać zgrupowanie, ale nie trzeba korzystać z przechwyconego wartość, która pochodzi z tradycyjnej (capturing) grupy.
  2. Skorzystaj z atomic group (lub podwykonań bez powrotu), jeśli dotyczy (?>pattern).
  3. Unikaj catastrophic backtracking podobnej do zarazy, projektując wyrażenia regularne, aby zakończyć wcześniej w przypadku niezgodności.

Stworzyłem film demonstrujący te techniki. Zacząłem od niezbyt dobrze napisanego wyrażenia regularnego w artykule catastrophic backtracking(x+x+)+y. A potem zrobiłem to 3 miliony razy szybciej po serii optymalizacji, testów porównawczych po każdej zmianie. Film jest specyficzne dla .NET, ale wiele z tych rzeczy stosuje się do większości innych regex smakach, a także:

.NET Regex Lesson: #5: Optimization