1

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 的事情,我们没有评估任何东西。我们只需要从文本的其余部分中提取 url。

我收到了这个问题,因为之前我试图解析电子邮件地址。在彻底搜索正则表达式之后,没有一个是 100% 准确的,并且有人对正则表达式的局限性提出了一些评论,以匹配 RFC 中电子邮件地址的确切 BNF 形式。因此可能需要语法(而不是正则表达式)。因此,我对 URL 有这个问题。

谢谢

4

2 回答 2

0

好吧,我认为使用一些关于http链接在自由文本中的外观的启发式方法可以更轻松地解决您的问题。它可以比这种复杂的正则表达式运行得更快,尤其是当我们谈论大文本时:

  1. http链接(url)以唯一开头http://
  2. 从头到尾 URL 不包含某些字符集(例如空格)。当你遇到这样的字符时,这意味着你找到了 URL 的结尾。
于 2013-06-04T07:51:02.740 回答
0

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

http://jsoup.org/

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

于 2013-06-04T07:54:04.983 回答