2016-04-01 10 views
0

Ich habe einen regulären Ausdruck, dass URLs in einem QuellcodeRegex - Optimieren Blick hinter

(?<!\b(XmlNamespace)\([^\n]{0,1000})"(http|ftp|socket):\/\/(?!www\.google-analytics\.com(\/collect)?)(\:(\d+)?)?("|\/))[\w\d] 

Aber es sehr langsam findet. Das Hauptproblem ist ein Blick zurück. Ich benutze Java (java.util.regex.Pattern) Kann mir bitte jemand helfen?

UPD:

Wenn ich geändert {0,1000} bis {0.100}, hat die Verarbeitungszeit auf 50 Sekunden geändert. Aber es ist keine Lösung. Ich glaube, dass dieser Blick hinter sich zuerst arbeitet, aber der Hauptteil nur Sekunde. So ist die Frage: Wie machen „(http | ftp | Buchse):. // Arbeit zuerst und schauen hinter erst danach

+0

Wie verwenden Sie diese Regex .. Sind Sie es nur einmal kompilieren oder sind Sie es nicht jedes Mal Ihre Methode Kompilierung aufgerufen wird? – TheLostMind

+0

Nur einmal natürlich. Ich benutze es nur für die Verarbeitung von ~ 5k Dateien und nur diese Regex funktioniert ~ 600 Sekunden, aber andere ohne hinter der Arbeit nicht mehr als 1 Sekunde. – Ivan

+1

Gut. Es funktioniert nicht so. Der Blick zurück wird zuerst betrachtet, und wenn er übereinstimmt, wird alles Folgende berücksichtigt. – TheLostMind

Antwort

1

Die Regex war tested at RegexPlanet

HINWEIS: Die (?!www\\.google-analytics\\.com(/collect)?) Look-Ahead tut machen nicht viel Sinn, da Sie : + Ziffern verbrauchen * nach //, so dass Ihre Regex könnte im allgemeinen ungültig.

ich wohne, wie kann das Muster verbessert werden.

Der Punkt ist, dass der Lookbehind in Ihrem Muster vor jedem Zeichen ausgelöst wird. Wenn Sie es nach dem ursprünglichen Muster wiederholen, wird dieses Muster nach dem Untermuster, das sich bereits in Ihrem Lookbehind befindet, es wird nur ausgelöst, nachdem dieses ursprüngliche Untermuster übereinstimmt.

Glücklicherweise ist Java Regex klug genug, um zu sehen, dass die Lookbehind-Breite mit dem Wechsel immer noch eine begrenzte Breite hat.

So

"(http|ftp|socket)://(?<!\bXmlNamespace\(.{0,1000}"(http|ftp|socket)://)(?!www\‌​.google-analytics\.com(/collect)?)(:\d*)?["/]\w 

Sollte besser funktionieren. Hinweis: Ich habe unnötige Escape-Symbole entfernt (/ ist kein Sonderzeichen in Java Regex), setzen Sie die ("|/) Alternation in eine Zeichenklasse [...]. Auch [\w\d] ist das gleiche wie \w (es entspricht bereits \d).

Die Regex war tested at RegexPlanet.

Java test:

String value1 = "\"http://:2123\"123"; 
String pattern1 = "\"(http|ftp|socket)://(?<!\\bXmlNamespace\\(.{0,1000}\"(http|ftp|socket)://)(?!www\\.google-analytics\\.com(/collect)?)(:\\d*)?[\"/]\\w"; 
Pattern ptrn = Pattern.compile(pattern1); 
Matcher matcher = ptrn.matcher(value1); 
if (matcher.find()) 
    System.out.println("true"); 
else 
    System.out.println("false");