美文网首页
Android正则表达式匹配URL

Android正则表达式匹配URL

作者: 路过麦田 | 来源:发表于2016-01-20 14:31 被阅读3604次

最近公司的即时通讯产品中需要用到正则表达式来匹配聊天信息中的网址,在表现形式上跟微信和QQ基本一致,但是这个正则写起来挺头疼的,正则表达式匹配网址历来就很有争议,没有完美的正则,只有满足业务场景的正则。之前用的是Android自带的表达式(android.util.Patterns),但是在不同的ROM上表现形式是不一样的,在一些比较诡异的case上基本识别不出来,后来不得不自己写一个,大体思路跟网上的差不多,我写的这个只是满足了我当前的业务需求,并不一定适合其他场景。

第一版用的是这个,HOST_NAME 用的Patterns类中的代码

String pattern = "([a-zA-z]+://[^\\s]*" + "|" + HOST_NAME + ")";

这个表达式只能笼统的匹配出来,但是会有很多错误,但是可以满足80%的业务场景。
sss://bac.bug 这种也会被匹配出来,而且像

http://www.baidu.com后面没有空格只有中文

会将后面的中文也一并匹配,只有遇到空格后才会停止

<u>http://www.baidu.com后面没有空格只有中文</u>

在QA发现越来越多的问题后,果断改了一下,后面所有的中文都将不会被匹配

String pattern = "([a-zA-z]+://[^\\u4e00-\\u9fa5\\s]*" + "|"  + HOST_NAME + ")";

这个表达式基本可以满足90%的业务场景,但是遇到下面这种:

http://www.baidu.com555先数字后中文

也会将数字匹配到

<u>http://www.baidu.com555</u>先数字后中文

而且针对不带协议头的网址识别就需要靠HOST_NAME这部分,这部分在不同ROM上识别结果又不一样,随着测试的深入,失败的case越来越多,最终也被淘汰了。

第三版也是现在正在用的正则:

// all domain names
private static final String[] ext = {
    "top", "com.cn", "com", "net", "org", "edu", "gov", "int", "mil", "cn", "tel", "biz", "cc", "tv", "info", 
    "name", "hk", "mobi", "asia", "cd", "travel", "pro", "museum", "coop", "aero", "ad", "ae", "af", 
    "ag", "ai", "al", "am", "an", "ao", "aq", "ar", "as", "at", "au", "aw", "az", "ba", "bb", "bd", 
    "be", "bf", "bg", "bh", "bi", "bj", "bm", "bn", "bo", "br", "bs", "bt", "bv", "bw", "by", "bz", 
    "ca", "cc", "cf", "cg", "ch", "ci", "ck", "cl", "cm", "cn", "co", "cq", "cr", "cu", "cv", "cx", 
    "cy", "cz", "de", "dj", "dk", "dm", "do", "dz", "ec", "ee", "eg", "eh", "es", "et", "ev", "fi", 
    "fj", "fk", "fm", "fo", "fr", "ga", "gb", "gd", "ge", "gf", "gh", "gi", "gl", "gm", "gn", "gp", 
    "gr", "gt", "gu", "gw", "gy", "hk", "hm", "hn", "hr", "ht", "hu", "id", "ie", "il", "in", "io", 
    "iq", "ir", "is", "it", "jm", "jo", "jp", "ke", "kg", "kh", "ki", "km", "kn", "kp", "kr", "kw", 
    "ky", "kz", "la", "lb", "lc", "li", "lk", "lr", "ls", "lt", "lu", "lv", "ly", "ma", "mc", "md", 
    "mg", "mh", "ml", "mm", "mn", "mo", "mp", "mq", "mr", "ms", "mt", "mv", "mw", "mx", "my", "mz",
    "na", "nc", "ne", "nf", "ng", "ni", "nl", "no", "np", "nr", "nt", "nu", "nz", "om", "qa", "pa", 
    "pe", "pf", "pg", "ph", "pk", "pl", "pm", "pn", "pr", "pt", "pw", "py", "re", "ro", "ru", "rw", 
    "sa", "sb", "sc", "sd", "se", "sg", "sh", "si", "sj", "sk", "sl", "sm", "sn", "so", "sr", "st", 
    "su", "sy", "sz", "tc", "td", "tf", "tg", "th", "tj", "tk", "tm", "tn", "to", "tp", "tr", "tt", 
    "tv", "tw", "tz", "ua", "ug", "uk", "us", "uy", "va", "vc", "ve", "vg", "vn", "vu", "wf", "ws", 
    "ye", "yu", "za", "zm", "zr", "zw"
};

static {   
    StringBuilder sb = new StringBuilder();   
    sb.append("(");   
    for (int i = 0; i < ext.length; i++) {      
        sb.append(ext[i]);      
        sb.append("|");   
    }   
    sb.deleteCharAt(sb.length() - 1);   
    sb.append(")");   
    // final pattern str
    String pattern = "((https?|s?ftp|irc[6s]?|git|afp|telnet|smb)://)?((\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})|((www\\.|[a-zA-Z\\.\\-]+\\.)?[a-zA-Z0-9\\-]+\\." + sb.toString() + "(:[0-9]{1,5})?))((/[a-zA-Z0-9\\./,;\\?'\\+&%\\$#=~_\\-]*)|([^\\u4e00-\\u9fa5\\s0-9a-zA-Z\\./,;\\?'\\+&%\\$#=~_\\-]*))";   
    // Log.v(TAG, "pattern = " + pattern);   
    WEB_URL = Pattern.compile(pattern);
}

这个正则基本上可以满足90%以上的业务场景,QA提出的case也完美通过,当然,有人可能会说有些这个表达式根本不严谨,好多匹配到的根本不是我想要的。确实,一个正则要完美匹配出所有的网址基本上是不可能的,而且还有IPv4,IPv6类的网址,更令人痛苦的还有中文域名,或者包含中文(没有被浏览器转义)的url,所以这里才会以业务场景为中心去编写正则,满足我所有的业务场景,那产品在这个环节就不会出现bug,这对我来说就已经OK了。

相关文章

  • nginx中location指令说明

    该指令用于匹配URL 语法如下: = :用于不含正则表达式的 url 前,要求请求字符串与 url 严格匹配,如果...

  • url正则 有测试用例

    js匹配网址url的正则表达式集合 方法 测试

  • Android正则表达式匹配URL

    最近公司的即时通讯产品中需要用到正则表达式来匹配聊天信息中的网址,在表现形式上跟微信和QQ基本一致,但是这个正则写...

  • Fiddler 代理文件夹和文件

    代理文件 匹配生产URL正则表达式 regex:http://www.a.com/statics/js/(.*)[...

  • JS常用各种正则表达式

    原文链接 匹配url 这个url的正则表达式判断的JavaScript!比较全面的。它验证的情况包括IP,域名(d...

  • Flutter 获取 Url 域名

    Flutter 截取url 的域名 两种方式 1 通过正则匹配截取 通过正则表达式截取匹配的域名 2 通过Flut...

  • 用正则表达式匹配3的倍数

    之前在知乎上看到了有人用正则表达式匹配3的倍数,不觉呀然一惊,原来正则表达式还能这么用,匹配邮箱、URL简直是太弱...

  • Android利用正则表达式如何匹配URL

    在Android项目中遇到一个问题,需求是需要获取浏览器分享出来的内容中的URL。 正常情况下分享出来的URL信息...

  • Python简单爬虫 - 正则表达式

    Python爬虫快速上手,使用正则表达式匹配出网页中图片的URL,实现网页图片的批量下载: 007 - Pytho...

  • Nginx 匹配规则

    无 :默认匹配,普通匹配 = :精确匹配 ~* :匹配正则表达式,不区分大小写 ~ :匹配正则表达式,区分大小写 ...

网友评论

      本文标题:Android正则表达式匹配URL

      本文链接:https://www.haomeiwen.com/subject/zbklkttx.html