I didnβt like any of the implementations (because they use Regex, which is an expensive operation, or a library that is redundant if you only need one method), so I ended up using the java.net.URI class with some additional checks and a restriction Protocols: http, https, file, ftp, mailto, news, urn.
And yes, catching an exception can be an expensive operation, but probably not as bad as regular expressions:
final static Set<String> protocols, protocolsWithHost; static { protocolsWithHost = new HashSet<String>( Arrays.asList( new String[]{ "file", "ftp", "http", "https" } ) ); protocols = new HashSet<String>( Arrays.asList( new String[]{ "mailto", "news", "urn" } ) ); protocols.addAll(protocolsWithHost); } public static boolean isURI(String str) { int colon = str.indexOf(':'); if (colon < 3) return false; String proto = str.substring(0, colon).toLowerCase(); if (!protocols.contains(proto)) return false; try { URI uri = new URI(str); if (protocolsWithHost.contains(proto)) { if (uri.getHost() == null) return false; String path = uri.getPath(); if (path != null) { for (int i=path.length()-1; i >= 0; i--) { if ("?<>:*|\"".indexOf( path.charAt(i) ) > -1) return false; } } } return true; } catch ( Exception ex ) {} return false; }
isapir Jun 25 '13 at 9:12 2013-06-25 09:12
source share