2012-04-18 21 views
11

Kiedy biegnę

/^(.+)+Q$/.test("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX") 

w Chrome lub IE, trwa ~ 10 sekund. (Firefox jest w stanie to ocenić prawie natychmiast.)

Dlaczego zajmuje to tyle czasu? (I dlaczego/w jaki sposób Firefox potrafi to zrobić tak szybko?)

(Oczywiście, nigdy bym nie uruchamiał tego konkretnego regexu, ale trafiam na podobny problem z wyrażeniem URL pod adresem http://daringfireball.net/2010/07/improved_regex_for_matching_urls i wydaje mi się, że sprowadzają się do tego, to istnieją pewne adresy URL, które spowodują, że przeglądarka zamknąć)

na przykład:

var re = /\b((?:https?:\/\/|www\d{0,3}[.]|[a-z0-9.\-]+[.][a-z]{2,4}\/)(?:[^\s()<>]+|\(([^\s()<>]+|(\([^\s()<>]+\)))*\))+(?:\(([^\s()<>]+|(\([^\s()<>]+\)))*\)|[^\s`!()\[\]{};:'".,<>?«»“”‘’]))/i; 
re.test("http://google.com/?q=(AAAAAAAAAAAAAAAAAAAAAAAAAAAAA") 
+11

http://www.regular-expressions.info/catastrophic.html – georg

+2

Jednym z powodów może być to, że robi dużo backtracking. Nie wyjaśnia to jednak, dlaczego Firefox działa szybciej. Może mają dodatkową optymalizację. Jeśli chcesz dowiedzieć się więcej o wewnętrznych działaniach silników regex, sugeruję przeczytać http://shop.oreilly.com/product/9780596528126.do –

+0

@thg opublikuj to jako odpowiedź, proszę –

Odpowiedz

8

jak wskazano thg435, to brzmi jak katastrofalnego back-tracking. Istnieje doskonały artykuł na ten temat, Regular Expression Matching Can Be Simple And Fast.

Opisuje efektywne podejście znane jako Thompson NFA. Jak jednak wspomniano, nie obsługuje to wszystkich funkcji współczesnych wyrażeń regularnych. Na przykład nie może tworzyć odsyłaczy wstecz. Jednak, jak zaproponowano w art.

„Mimo to, byłoby rozsądne, aby korzystać NFA symulację Thompson za wyrażeń najbardziej regularnie, a tylko wydobyć backtracking gdy jest Potrzebna jest szczególnie mądry realizacja może połączyć dwa, , odwołując się do wycofywania tylko w celu dostosowania do referencji. "

Podejrzewam, że może to robić Firefox.

+2

Jeśli powiedział to w komentarzu, czy nie powinien opublikować go jako answeR? –

+2

@Martin., Dostarczam zupełnie inny artykuł. I nigdy nie powiedziałem, że nie powinien publikować odpowiedzi. –

+1

cóż, wysłałeś odpowiedź zanim opublikowałeś link –

Powiązane problemy