Patterns.WEB_URL.matcher(str)的错误行为

时间:2015-04-21 11:26:03

标签: java android regex

我在我的应用中使用Patterns.WEB_URL.matcher(str)来验证我的应用中的网址。这个api在前Lollipop API中非常有用。但是,在Lollipop中它甚至可以验证“abd.def”。奇怪和越野行为。任何修复的建议/想法?

2 个答案:

答案 0 :(得分:6)

  

奇怪和错误的行为

使用固件烘焙的正则表达式定义为“buggy”。

顶级域名(TLD)名单一直在稳步扩展。任何试图限制当时已知TLD的正则表达式最终都会过时。所以,12个月前,Google工程师changed the regex to accept any TLD, so long as it uses the proper characters。另一种是关于有效URL如何通过正则表达式失败的永无止境的错误报告系列,当这些版本的Android发布时,这些URL无效。

  

修复的任何建议/想法?

编写自己的正则表达式。或者,分叉较旧的正则表达式并维护自己的有效TLD列表。或者,通过其他方式验证URL。或者,找一个积极维护图书馆的人,允许你这样做,确保你不断更新你对图书馆的使用,以考虑新的顶级域名。

IOW,执行与固件无关的操作,并确保在有效TLD的更改方面保持准确性。

答案 1 :(得分:1)

为了扩展CommonsWare的答案,以下是我用来避免Linkify链接看似随机的文本:

Linkify.TransformFilter filter = new Linkify.TransformFilter() {
        public final String transformUrl(final Matcher match, String url) {
            return match.group();
        }
    };

    Pattern webURL = Pattern.compile(new StringBuilder()
                    .append("((?:(http|https|Http|Https|rtsp|Rtsp):")
                    .append("\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)")
                    .append("\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_")
                    .append("\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?")
                    .append("((?:(?:[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}\\.)+")   // named host
                    .append("(?:")   // plus top level domain
                    .append("(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])")
                    .append("|(?:biz|b[abdefghijmnorstvwyz])")
                    .append("|(?:cat|com|coop|c[acdfghiklmnoruvxyz])")
                    .append("|d[ejkmoz]")
                    .append("|(?:edu|e[cegrstu])")
                    .append("|f[ijkmor]")
                    .append("|(?:gov|g[abdefghilmnpqrstuwy])")
                    .append("|h[kmnrtu]")
                    .append("|(?:info|int|i[delmnoqrst])")
                    .append("|(?:jobs|j[emop])")
                    .append("|k[eghimnrwyz]")
                    .append("|l[abcikrstuvy]")
                    .append("|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])")
                    .append("|(?:name|net|n[acefgilopruz])")
                    .append("|(?:org|om)")
                    .append("|(?:pro|p[aefghklmnrstwy])")
                    .append("|qa")
                    .append("|r[eouw]")
                    .append("|s[abcdeghijklmnortuvyz]")
                    .append("|(?:tel|travel|t[cdfghjklmnoprtvwz])")
                    .append("|u[agkmsyz]")
                    .append("|v[aceginu]")
                    .append("|w[fs]")
                    .append("|y[etu]")
                    .append("|z[amw]))")
                    .append("|(?:(?:25[0-5]|2[0-4]") // or ip address
                    .append("[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(?:25[0-5]|2[0-4][0-9]")
                    .append("|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1]")
                    .append("[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}")
                    .append("|[1-9][0-9]|[0-9])))")
                    .append("(?:\\:\\d{1,5})?)") // plus option port number
                    .append("(\\/(?:(?:[a-zA-Z0-9\\;\\/\\?\\:\\@\\&\\=\\#\\~")  // plus option query params
                    .append("\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?")
                    .append("(?:\\b|$)").toString()
    );

    Linkify.addLinks(myTextView, webURL, null, null, filter);