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 有这个问题。
谢谢