2016-04-01 2 views
0

У меня есть регулярное выражение, которое находит адреса в исходном кодеRegex - Оптимизировать вид сзади

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

Но это очень медленно. Главная проблема - заглянуть. Я использую Java (java.util.regex.Pattern) Может ли кто-нибудь помочь мне, пожалуйста?

UPD:

Когда я изменил {0,1000} до {0,100}, время обработки изменилась до 50 секунд. Но это не решение. Я считаю, что этот взгляд за работой сначала, но основная часть - только вторая. Таким образом, вопрос: Как сделать «(HTTP | FTP | сокет):. // работа первого и оглядывайся только после этого

+0

Как вы используете это регулярное выражение .. Вы компилировать его только один раз, или вы компиляции его каждый раз, когда ваш метод называется? – TheLostMind

+0

Только один раз, конечно. Просто я использую его для обработки ~ 5k файлов, и только это регулярное выражение работает ~ 600 секунд, но другое, не смотря за работу не более 1 секунды. – Ivan

+1

Ну. Это не работает. Взгляд сзади считается первым, и когда он будет соответствовать, все последующее будет рассмотрено. – TheLostMind

ответ

1

Регулярное выражение было tested at RegexPlanet

ПРИМЕЧАНИЕ: (?!www\\.google-analytics\\.com(/collect)?) опережения делает не имеет особого смысла, так как вы потребляете : + цифры * после //, поэтому ваше регулярное выражение может быть недействительным в целом.

Я останавливаюсь на том, как модель может быть повышена.

Дело в том, что lookbehind в вашем шаблоне запускается при распределении перед каждым персонажем. Если вы поместите его после первоначального шаблона , повторяющего этот шаблон после подшаблона, который уже находится в вашем образе, он будет запущен только после сопоставления этого начального подшаблона.

К счастью, Java regex достаточно мудр, чтобы видеть, что ширина lookbehind по-прежнему ограничена шириной с чередованием.

Так,

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

Должно работать лучше. Примечание. Я удалил ненужные символы escape (/ не является специальным символом в Java regex), поместите чередование ("|/) в класс символов [...]. Кроме того, [\w\d] совпадает с \w (он уже соответствует \d).

Регулярное выражение было 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"); 
Смежные вопросы