语法与解析URL的正则表达式?

时间:2013-06-04 07:36:18

标签: java regex

URL中提到了BNF形式的URL:

http://www.w3.org/Addressing/rfc1738.txt

我需要做的是从html文本中提取URL。现在我想知道我可以代表

            String alpha       = "[a-zA-Z]";
    String alphadigit  = "[a-zA-Z0-9]";
    String domainlabel = alphadigit+"|"+alphadigit+"("+alphadigit+"|-)*?"+alphadigit;       
    //String toplabel  = alpha+"|"+alpha+"("+alphadigit+"|-)*?"+alphadigit;
    String toplabel    = "com|org|net|mil|edu|(co\\.[a-z]+)";
    String hostname    = "(("+domainlabel+")\\.)*("+toplabel+")";
    String hostport    = hostname;

    String lowalpha    = "([a-z])";
    String hialpha     = "([A-Z])";
    String alpha       = "("+lowalpha+"|"+hialpha+")";
    String digit       = "([0-9])";
        String safe        = "($|-|_|.|\\+)";
    String extra       = "(!|\\*|'|\\(|\\)|,)";
    //String national    = "{" | "}" | "|" | "\" | "^" | "~" | "[" | "]" | "`";
    String punctuation = "(<|>|#|%|\")";
    String reserved    = "(;|/|?|:|@|&|=)";
    String hex         = "("+digit+"[A-Fa-f]"+")";
    String escape      = "(%"+hex+hex+")";
    String unreserved  = "("+alpha+"|"+digit+"|"+safe+"|"+extra+")";
    String uchar       = "("+unreserved+"|"+escape+")";
        String hsegment    = "(("+uchar+"|;|:|@|&|=)*)";
        String search      = "("+uchar+"|;|:|@|&|=)?)";
    String hpath       = hsegment+"(/"+hsegment+")*";
    //String httpurl = "http://"+hostport+"(/"+hpath+"(?"+search+")?)?";
    String httpurl = "http://"+hostport+"/"+hpath;

最终的正则表达式:

http://(([a-zA-Z0-9]|[a-zA-Z0-9]([a-zA-Z0-9]|-)*?[a-zA-Z0-9])\.)*(com|org|net|mil|edu|(co\.[a-z]+))/(((((([a-z])|([A-Z]))|([0-9])|($|-|_|.|\+)|(!|\*|'|\(|\)|,))|(%(([0-9])[A-Fa-f])(([0-9])[A-Fa-f])))|;|:|@|&|=)*)(/(((((([a-z])|([A-Z]))|([0-9])|($|-|_|.|\+)|(!|\*|'|\(|\)|,))|(%(([0-9])[A-Fa-f])(([0-9])[A-Fa-f])))|;|:|@|&|=)*))*

所以你可以看到我将整个BNF表示为一个大的正则表达式,它将与javax.util.regex方法一起用于从文本中提取URL。现在这是正确的方法吗?如果它是正确的,那么为什么我们需要编写一个无上下文语法?正则表达式方法有哪些缺点?

此外,对于语法分析器,比如语言,语法用于验证代码是否遵循语法规则,否则显示一些错误消息。同样使用语法我们得到一个语法树,用于评估表达式。对于URL的事情,我们没有评估任何东西。我们只需要从文本的其余部分中提取网址。

我有这个问题,因为以前我试图解析电子邮件地址。在详尽地搜索正则表达式后,其中没有一个证明是100%准确的,并且对正则表达式的限制进行了一些评论,以匹配RFC中确切的BNF形式的电子邮件地址。因此可能需要语法(而不是正则表达式)。因此我对URL有这个问题。

由于

2 个答案:

答案 0 :(得分:0)

嗯,我认为使用一些关于http链接在自由文本中的样子的启发式方法可以更轻松地解决您的问题。它可以比这种复杂的正则表达式更快地工作,特别是如果我们谈论的是大文本:

  1. http link(url)以唯一http://
  2. 开头
  3. 从头到尾URL不包含一些字符集(例如白色空格)。当你跨过这样的角色时,就意味着你找到了URL的结尾。

答案 1 :(得分:0)

如果要提取的URL在标记内(例如锚标记的href属性),那么我建议使用JSoup来解析和检查HTML。

http://jsoup.org/

在文本正文中,我确信可以采用更简单的正则表达式方法,可能与协议匹配(http://)