这个正则表达式有什么问题?

时间:2010-11-05 08:01:20

标签: java regex

我在Java上尝试以下代码:

String test = "http://asda.aasd.sd.google.com/asdasdawrqwfqwfqwfqwf";
String regex = "[http://]{0,1}([a-zA-Z]*.)*\\.google\\.com/[-a-zA-Z/_.?&=]*";
System.out.println(test.matches(regex));

它可以工作几分钟(之后我杀了VM)没有结果。 任何人都可以帮助我吗?

顺便说一句:你会建议我将来如何加快weblink-testng正则表达式?

6 个答案:

答案 0 :(得分:7)

[http://]是一个字符类,意味着该字符集中的任何一个

如果必须http://开头,请关闭这些特定的方括号。如果是可选的,您可以使用(http://)?

一个显而易见的问题是你正在寻找序列([a-zA-Z]+.)*\\.google - 由于裸.这意味着“任何角色”,这将会进行回溯的批次而不是你想要的文字时期。

但即使您将其替换为的意思([a-zA-Z]+\\.)*\\.google,您仍有问题 - 这将需要在{{1}之前的两个.字符}。你应该尝试:

google

通过String regex = "(http://)?([a-zA-Z]+\\.)*google\\.com/[-a-zA-Z/_.?&=]*"; 匹配立即返回。

请注意,目前这需要true末尾的/。如果这是一个问题,这是一个小修复,但我已经把它留在那里,因为你已经在你的原始正则表达式。

答案 1 :(得分:4)

您正尝试使用方括号将该方案匹配为字符类。这意味着该集合中只有零个或一个字符。你想要一个带有圆括号的子模式。您也可以将{0,1}更改为?

此外,您应该删除google\\.com之前的句号,因为您已经在正则表达式的子域子模式中查找句点。正如切鲁维姆所指出的那样,你也忘了逃离那个时期。

String regex = "(http://)?([a-zA-Z]+\\.)*google\\.com/[-a-zA-Z/_.?&=]*";

答案 2 :(得分:3)

([a-zA-Z]*.)部分中,您需要转义.(因为现在它意味着“所有字符”)或将其删除。

答案 3 :(得分:2)

正则表达式存在两个问题。

第一个很容易,正如其他人所提到的那样。您需要将“http://”匹配为子模式,而不是字符类。将括号更改为括号。

第二个问题导致性能非常差。它导致正则表达式反复回溯,试图匹配模式。

您要做的是匹配零个或多个子域,这些子域是一组字母后跟一个点。由于您希望明确匹配点,请转义点。同时删除“google”前面的点,以便您可以匹配“http://google.com/etc”(即谷歌前面没有前导点)。

所以你的表达成为:

String regex = "(http://){0,1}([a-zA-Z]+\\.)*google\\.com/[-a-zA-Z/_.?&=]*";

在你的例子上运行这个正则表达式只需要几分之一秒。

答案 4 :(得分:1)

假设您已修复([a-zA-Z]*\\.),则需要将*更改为+,以便该部分变为([a-zA-Z]+\\.)。否则,您将接受http://...google.com,但这无效。

答案 5 :(得分:1)

通过在google.com之前对部分进行分组,我假设您正在寻找部分URL主机名。我认为rexep是强大的工具,但你可以简单地使用URL Java class。有getHost()方法。然后,您可以检查主机名是否以google.com结尾并将其拆分或使用一些只有主机名的简化regexp。

URL url = new URL("http://asda.aasd.sd.google.com/asdasdawrqwfqwfqwfqwf");
String host = url.getHost();
if (host.endsWith("google.com"))
    {
    String [] parts = host.split("\\.");
    for (String s: parts)
        System.out.println(s);
    }