Ich versuche, eine URL passende regulären Ausdruck zu verwenden, die ich von http://daringfireball.net/2010/07/improved_regex_for_matching_urls bekamWie kann ich diesen regulären Ausdruck nicht in "katastrophalen Backtracking" führen?
(?xi)
\b
( # Capture 1: entire matched URL
(?:
https?:// # http or https protocol
| # or
www\d{0,3}[.] # "www.", "www1.", "www2." … "www999."
| # or
[a-z0-9.\-]+[.][a-z]{2,4}/ # looks like domain name followed by a slash
)
(?: # One or more:
[^\s()<>]+ # Run of non-space, non-()<>
| # or
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
)+
(?: # End with:
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
| # or
[^\s`!()\[\]{};:'".,<>?«»“”‘’] # not a space or one of these punct chars
)
)
Basierend auf den Antworten auf another question, scheint es, dass es Fälle gibt, die diese Regex backtrack catastrophically verursachen. Zum Beispiel:
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)")
... kann eine wirklich lange Zeit in Anspruch nehmen auszuführen (zB in Chrome)
Es scheint mir, dass das Problem in diesem Teil des Codes liegt:
(?: # One or more:
[^\s()<>]+ # Run of non-space, non-()<>
| # or
\(([^\s()<>]+|(\([^\s()<>]+\)))*\) # balanced parens, up to 2 levels
)+
... das scheint (.+|\((.+|(\(.+\)))*\))+
etwa gleich zu sein, was aussieht wie es (.+)+
enthält
gibt es eine Änderung, die ich, dass das wird vermeiden machen?
Wirklich, Sie sollten diesen Regex wegwerfen und mit einem kommen, der tut, was Sie brauchen. Ich habe noch keine Anwendung gesehen, die sowohl flauschig genug ist, um einen Regex für URL-Parsing zu verwenden (anstelle eines echten Parsers), als auch ernst genug, um verschachtelte Klammern in einer URL zu verarbeiten. Beginnend mit "https?: //" und endend mit dem ersten Zeichen, das in einer korrekten URL% -codiert werden sollte, aber nicht mit fast allem umgehen kann und nicht dazu führt, dass der Regex-Matcher exponentiell wird. –
Haben Sie Rubular versucht? Es hat einen praktischen Spickzettel darunter und Sie können alle Arten von Testausdrücken hinzufügen, um sicherzustellen, dass es funktioniert. (P.S. Ich weiß, das ist für js, aber das ist immer noch eine praktische Ressource.) Http://rubular.com/ – Edwin