正则表达式 - 优化背后的外观

时间:2016-04-01 13:17:56

标签: java 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秒。但它不是解决方案。我认为这种背后的效果首先是有效的,但主要部分只是第二种。所以问题:如何制作&#34;(http | ftp | socket)://先工作,然后再看后面?

1 个答案:

答案 0 :(得分:1)

正则表达式为tested at RegexPlanet

注意(?!www\\.google-analytics\\.com(/collect)?)前瞻没有多大意义,因为您在:之后消费// +位数*,因此您的正则表达式可能一般无效

我详细介绍了如何增强模式

关键是你的模式中的lookbehind是在每个角色之前的alocation处触发的。如果将它放在初始模式之后,在已经在lookbehind 中的子模式之后重复此模式,则只有在匹配此初始子模式后才会触发它。

幸运的是,Java正则表达式足够明智,看到后面的宽度仍然受到交替的约束宽度。

所以,

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

应该更好地工作。注意我删除了不必要的转义符号(/不是Java正则表达式中的特殊字符),将("|/)替换放入字符类[...]。此外,[\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");