求一个能匹配所有超链接的正则表达式.如题 
需要能匹配所有url例如: 
http://www.13.com 
https://www.asdf.com.cn/asdf 
www.23.com 
http://www.123.com:2563/tsf(端口不能超过65535,端口不能出现在子域中,如:http://www.abc.com/ab:2525/a.asp,这个不能算是正确的url吧) 
http://www.123.com:2563/tsf/a.html?a=2&&b=abc 
http://www.aa.com/servlet 
http://ee.com/abcSerlvet?a=8&&b=asdf 
ftp://192.168.0.2:8080 
http://ww.ss.com/////(这样是正确的可以访问) 
等等,尽量写一个完美的正则表达式。 
请求帮助 

解决方案 »

  1.   

    2#http://topic.csdn.net/u/20080911/09/a2484fbd-55e1-4cd2-829b-ec720ca646fc.html
      

  2.   

    http://topic.csdn.net/u/20080911/09/a2484fbd-55e1-4cd2-829b-ec720ca646fc.html
      

  3.   

    暂时我写成如下:还需要完善,请大家先拿去优化。    /**
         * 超链接正则表达式,不完整,不能匹配servlet
         * regHref="^http://\\w+(\\.\\w+|)+(/\\w+)*(/\\w+\\.(\\w+|))?"
         */
        String[] href=new String[]{" http://www.qq.com","asdfasdf","www.qq.com:5060423423/asb","ftp://www.abc.cn.abc.comc.c////","http://testServlet","http://test/testServlet","http://www.qq.com/test/a.html","http://www.qq.com/test/a.htmla.html"};
        String regHref="^\\s*((http(s)?://)|(ftp://)|())\\w+(\\.\\w+)+((:\\d{1,5})|)(/\\w*)*(/\\w+\\.(\\w+|))?([\\w- ./?%&=]*)?";
        for (int i = 0; i < href.length; i++) {
          href[i]=href[i].replaceAll("\\s", "");//去掉空字符,包括空格、回车、换行
          System.out.println(href[i]+"是超链接?"+href[i].matches(regHref));
        }
      

  4.   

    其实apache的validator包已经给了URL验证了我把这个类的代码贴下 借鉴下吧import java.io.Serializable;
    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.Set;import org.apache.commons.validator.util.Flags;
    import org.apache.oro.text.perl.Perl5Util;/**
     * <p>Validates URLs.</p>
     * Behavour of validation is modified by passing in options:
     * <li>ALLOW_2_SLASHES - [FALSE]  Allows double '/' characters in the path
     * component.</li>
     * <li>NO_FRAGMENT- [FALSE]  By default fragments are allowed, if this option is
     * included then fragments are flagged as illegal.</li>
     * <li>ALLOW_ALL_SCHEMES - [FALSE] By default only http, https, and ftp are
     * considered valid schemes.  Enabling this option will let any scheme pass validation.</li>
     *
     * <p>Originally based in on php script by Debbie Dyer, validation.php v1.2b, Date: 03/07/02,
     * http://javascript.internet.com. However, this validation now bears little resemblance
     * to the php original.</p>
     * <pre>
     *   Example of usage:
     *   Construct a UrlValidator with valid schemes of "http", and "https".
     *
     *    String[] schemes = {"http","https"}.
     *    UrlValidator urlValidator = new UrlValidator(schemes);
     *    if (urlValidator.isValid("ftp://foo.bar.com/")) {
     *       System.out.println("url is valid");
     *    } else {
     *       System.out.println("url is invalid");
     *    }
     *
     *    prints "url is invalid"
     *   If instead the default constructor is used.
     *
     *    UrlValidator urlValidator = new UrlValidator();
     *    if (urlValidator.isValid("ftp://foo.bar.com/")) {
     *       System.out.println("url is valid");
     *    } else {
     *       System.out.println("url is invalid");
     *    }
     *
     *   prints out "url is valid"
     *  </pre>
     *
     * @see
     * <a href='http://www.ietf.org/rfc/rfc2396.txt' >
     *  Uniform Resource Identifiers (URI): Generic Syntax
     * </a>
     *
     * @version $Revision: 478334 $ $Date: 2006-11-22 21:31:54 +0000 (Wed, 22 Nov 2006) $
     * @since Validator 1.1
     */
    public class UrlValidator implements Serializable {    /**
         * Allows all validly formatted schemes to pass validation instead of 
         * supplying a set of valid schemes.
         */
        public static final int ALLOW_ALL_SCHEMES = 1 << 0;    /**
         * Allow two slashes in the path component of the URL.
         */
        public static final int ALLOW_2_SLASHES = 1 << 1;    /**
         * Enabling this options disallows any URL fragments.
         */
        public static final int NO_FRAGMENTS = 1 << 2;    private static final String ALPHA_CHARS = "a-zA-Z";    private static final String ALPHA_NUMERIC_CHARS = ALPHA_CHARS + "\\d";    private static final String SPECIAL_CHARS = ";/@&=,.?:+$";    private static final String VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]";    private static final String SCHEME_CHARS = ALPHA_CHARS;    // Drop numeric, and  "+-." for now
        private static final String AUTHORITY_CHARS = ALPHA_NUMERIC_CHARS + "\\-\\.";    private static final String ATOM = VALID_CHARS + '+';    /**
         * This expression derived/taken from the BNF for URI (RFC2396).
         */
        private static final String URL_PATTERN =
                "/^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?/";
        //                                                                      12            3  4          5       6   7        8 9    /**
         * Schema/Protocol (ie. http:, ftp:, file:, etc).
         */
        private static final int PARSE_URL_SCHEME = 2;    /**
         * Includes hostname/ip and port number.
         */
        private static final int PARSE_URL_AUTHORITY = 4;    private static final int PARSE_URL_PATH = 5;    private static final int PARSE_URL_QUERY = 7;    private static final int PARSE_URL_FRAGMENT = 9;    /**
         * Protocol (ie. http:, ftp:,https:).
         */
        private static final String SCHEME_PATTERN = "/^[" + SCHEME_CHARS + "]/";    private static final String AUTHORITY_PATTERN =
                "/^([" + AUTHORITY_CHARS + "]*)(:\\d*)?(.*)?/";
        //                                                                            1                          2  3       4    private static final int PARSE_AUTHORITY_HOST_IP = 1;    private static final int PARSE_AUTHORITY_PORT = 2;    /**
         * Should always be empty.
         */
        private static final int PARSE_AUTHORITY_EXTRA = 3;    private static final String PATH_PATTERN = "/^(/[-\\w:@&?=+,.!/~*'%$_;]*)?$/";    private static final String QUERY_PATTERN = "/^(.*)$/";    private static final String LEGAL_ASCII_PATTERN = "/^[\\000-\\177]+$/";    private static final String IP_V4_DOMAIN_PATTERN =
                "/^(\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})[.](\\d{1,3})$/";    private static final String DOMAIN_PATTERN =
                "/^" + ATOM + "(\\." + ATOM + ")*$/";    private static final String PORT_PATTERN = "/^:(\\d{1,5})$/";    private static final String ATOM_PATTERN = "/(" + ATOM + ")/";    private static final String ALPHA_PATTERN = "/^[" + ALPHA_CHARS + "]/";    /**
         * Holds the set of current validation options.
         */
        private Flags options = null;    /**
         * The set of schemes that are allowed to be in a URL.
         */
        private Set allowedSchemes = new HashSet();    /**
         * If no schemes are provided, default to this set.
         */
        protected String[] defaultSchemes = {"http", "https", "ftp"};    /**
         * Create a UrlValidator with default properties.
         */
        public UrlValidator() {
            this(null);
        }    /**
         * Behavior of validation is modified by passing in several strings options:
         * @param schemes Pass in one or more url schemes to consider valid, passing in
         *        a null will default to "http,https,ftp" being valid.
         *        If a non-null schemes is specified then all valid schemes must
         *        be specified. Setting the ALLOW_ALL_SCHEMES option will
         *        ignore the contents of schemes.
         */
        public UrlValidator(String[] schemes) {
            this(schemes, 0);
        }    /**
         * Initialize a UrlValidator with the given validation options.
         * @param options The options should be set using the public constants declared in
         * this class.  To set multiple options you simply add them together.  For example,
         * ALLOW_2_SLASHES + NO_FRAGMENTS enables both of those options.
         */
        public UrlValidator(int options) {
            this(null, options);
        }    /**
         * Behavour of validation is modified by passing in options:
         * @param schemes The set of valid schemes.
         * @param options The options should be set using the public constants declared in
         * this class.  To set multiple options you simply add them together.  For example,
         * ALLOW_2_SLASHES + NO_FRAGMENTS enables both of those options.
         */
        public UrlValidator(String[] schemes, int options) {
            this.options = new Flags(options);        if (this.options.isOn(ALLOW_ALL_SCHEMES)) {
                return;
            }        if (schemes == null) {
                schemes = this.defaultSchemes;
            }        this.allowedSchemes.addAll(Arrays.asList(schemes));
        }
      

  5.   

    接着上    /**
         * <p>Checks if a field has a valid url address.</p>
         *
         * @param value The value validation is being performed on.  A <code>null</code>
         * value is considered invalid.
         * @return true if the url is valid.
         */
        public boolean isValid(String value) {
            if (value == null) {
                return false;
            }        Perl5Util matchUrlPat = new Perl5Util();
            Perl5Util matchAsciiPat = new Perl5Util();        if (!matchAsciiPat.match(LEGAL_ASCII_PATTERN, value)) {
                return false;
            }        // Check the whole url address structure
            if (!matchUrlPat.match(URL_PATTERN, value)) {
                return false;
            }        if (!isValidScheme(matchUrlPat.group(PARSE_URL_SCHEME))) {
                return false;
            }        if (!isValidAuthority(matchUrlPat.group(PARSE_URL_AUTHORITY))) {
                return false;
            }        if (!isValidPath(matchUrlPat.group(PARSE_URL_PATH))) {
                return false;
            }        if (!isValidQuery(matchUrlPat.group(PARSE_URL_QUERY))) {
                return false;
            }        if (!isValidFragment(matchUrlPat.group(PARSE_URL_FRAGMENT))) {
                return false;
            }        return true;
        }    /**
         * Validate scheme. If schemes[] was initialized to a non null,
         * then only those scheme's are allowed.  Note this is slightly different
         * than for the constructor.
         * @param scheme The scheme to validate.  A <code>null</code> value is considered
         * invalid.
         * @return true if valid.
         */
        protected boolean isValidScheme(String scheme) {
            if (scheme == null) {
                return false;
            }        Perl5Util schemeMatcher = new Perl5Util();
            if (!schemeMatcher.match(SCHEME_PATTERN, scheme)) {
                return false;
            }        if (this.options.isOff(ALLOW_ALL_SCHEMES)) {            if (!this.allowedSchemes.contains(scheme)) {
                    return false;
                }
            }        return true;
        }    /**
         * Returns true if the authority is properly formatted.  An authority is the combination
         * of hostname and port.  A <code>null</code> authority value is considered invalid.
         * @param authority Authority value to validate.
         * @return true if authority (hostname and port) is valid.
         */
        protected boolean isValidAuthority(String authority) {
            if (authority == null) {
                return false;
            }        Perl5Util authorityMatcher = new Perl5Util();
            Perl5Util matchIPV4Pat = new Perl5Util();        if (!authorityMatcher.match(AUTHORITY_PATTERN, authority)) {
                return false;
            }        boolean ipV4Address = false;
            boolean hostname = false;
    // check if authority is IP address or hostname
            String hostIP = authorityMatcher.group(PARSE_AUTHORITY_HOST_IP);
            ipV4Address = matchIPV4Pat.match(IP_V4_DOMAIN_PATTERN, hostIP);        if (ipV4Address) {
                // this is an IP address so check components
                for (int i = 1; i <= 4; i++) {
                    String ipSegment = matchIPV4Pat.group(i);
                    if (ipSegment == null || ipSegment.length() <= 0) {
                        return false;
                    }                try {
                        if (Integer.parseInt(ipSegment) > 255) {
                            return false;
                        }
                    } catch(NumberFormatException e) {
                        return false;
                    }            }
            } else {
                // Domain is hostname name
                Perl5Util domainMatcher = new Perl5Util();
                hostname = domainMatcher.match(DOMAIN_PATTERN, hostIP);
            }//rightmost hostname will never start with a digit.
            if (hostname) {
                // LOW-TECH FIX FOR VALIDATOR-202
                // TODO: Rewrite to use ArrayList and .add semantics: see VALIDATOR-203
                char[] chars = hostIP.toCharArray();
                int size = 1;
                for(int i=0; i<chars.length; i++) {
                    if(chars[i] == '.') {
                        size++;
                    }
                }
                String[] domainSegment = new String[size];
                boolean match = true;
                int segmentCount = 0;
                int segmentLength = 0;
                Perl5Util atomMatcher = new Perl5Util();            while (match) {
                    match = atomMatcher.match(ATOM_PATTERN, hostIP);
                    if (match) {
                        domainSegment[segmentCount] = atomMatcher.group(1);
                        segmentLength = domainSegment[segmentCount].length() + 1;
                        hostIP =
                                (segmentLength >= hostIP.length())
                                ? ""
                                : hostIP.substring(segmentLength);                    segmentCount++;
                    }
                }
                String topLevel = domainSegment[segmentCount - 1];
                if (topLevel.length() < 2 || topLevel.length() > 4) {
                    return false;
                }            // First letter of top level must be a alpha
                Perl5Util alphaMatcher = new Perl5Util();
                if (!alphaMatcher.match(ALPHA_PATTERN, topLevel.substring(0, 1))) {
                    return false;
                }            // Make sure there's a host name preceding the authority.
                if (segmentCount < 2) {
                    return false;
                }
            }        if (!hostname && !ipV4Address) {
                return false;
            }        String port = authorityMatcher.group(PARSE_AUTHORITY_PORT);
            if (port != null) {
                Perl5Util portMatcher = new Perl5Util();
                if (!portMatcher.match(PORT_PATTERN, port)) {
                    return false;
                }
            }        String extra = authorityMatcher.group(PARSE_AUTHORITY_EXTRA);
            if (!GenericValidator.isBlankOrNull(extra)) {
                return false;
            }        return true;
        }
      

  6.   

    再接上面 /**
         * Returns true if the path is valid.  A <code>null</code> value is considered invalid.
         * @param path Path value to validate.
         * @return true if path is valid.
         */
        protected boolean isValidPath(String path) {
            if (path == null) {
                return false;
            }        Perl5Util pathMatcher = new Perl5Util();        if (!pathMatcher.match(PATH_PATTERN, path)) {
                return false;
            }        int slash2Count = countToken("//", path);
            if (this.options.isOff(ALLOW_2_SLASHES) && (slash2Count > 0)) {
                return false;
            }        int slashCount = countToken("/", path);
            int dot2Count = countToken("..", path);
            if (dot2Count > 0) {
                if ((slashCount - slash2Count - 1) <= dot2Count) {
                    return false;
                }
            }        return true;
        }    /**
         * Returns true if the query is null or it's a properly formatted query string.
         * @param query Query value to validate.
         * @return true if query is valid.
         */
        protected boolean isValidQuery(String query) {
            if (query == null) {
                return true;
            }        Perl5Util queryMatcher = new Perl5Util();
            return queryMatcher.match(QUERY_PATTERN, query);
        }    /**
         * Returns true if the given fragment is null or fragments are allowed.
         * @param fragment Fragment value to validate.
         * @return true if fragment is valid.
         */
        protected boolean isValidFragment(String fragment) {
            if (fragment == null) {
                return true;
            }        return this.options.isOff(NO_FRAGMENTS);
        }    /**
         * Returns the number of times the token appears in the target.
         * @param token Token value to be counted.
         * @param target Target value to count tokens in.
         * @return the number of tokens.
         */
        protected int countToken(String token, String target) {
            int tokenIndex = 0;
            int count = 0;
            while (tokenIndex != -1) {
                tokenIndex = target.indexOf(token, tokenIndex);
                if (tokenIndex > -1) {
                    tokenIndex++;
                    count++;
                }
            }
            return count;
        }
    }
      

  7.   

    org.apache.oro.text.perl.Perl5Util
    包是Jakarta 的 oro 项目中的
      

  8.   

    经过验证不能满足要求。比如:http::/asdfasd.com它也算是url了,还有:http://www.abc.com:2342304708209348/sadfasdfh.html也算,这样的能算是url了,端口都超过65535了,所以目前为止还没有能满足的
      

  9.   

    你是在什么里用,如果是在源码里找的话,url都会用<a href="" ..></a>这样的对子表示的,这样的话,
    只要用<a href=\"([^\"]+)\"[^>]*>[^<]+</a>就可以了,
      

  10.   

    我要用在类似QQ这样聊天里面,我要从一个文本里分析出所有URL,之后给它展现成一样超链接形式。这样正则表达式估计不太好弄,QQ上面的都不太完善。希望大家共同想个办法,完善这个URL的正则表达式。
      

  11.   

    to 楼主:所有url,看你的需求,你自己都不能说出到底哪些是合法的吧,
    举个例子http://www.baidu.com  ok
    www.baidu.com         ok
    baidu.com             (ok?) 如果只为了能上网,我想这个也是合法的匹配servlethttp://testServlet   ok
    http://testServlet/abc ok
    testServlet/abc        (ok?)好多例子,而且Url 还可以加上参数,更多繁琐的,你怎么匹配?
    由此,只能根据你的需求来定制,想囊括所有的,怕是不可能
      

  12.   

    介绍给你一个超级珍贵的正则表达式网站,关于URL的正则表达式链接如下:
    http://regexlib.com/Search.aspx?k=URL
      

  13.   

    22 楼说的网站可以去看看,那里可以说是正则表达式库了,不过是用 .net 写的。
      

  14.   

    像这种复杂的表达式得采用分而治之原则,一块一块地写,如果不是这样的话,
    写到后面都不知道自己在写什么了。这样做的好处在于,如果哪一段不正确了,可以很快地进行定位并修正。import java.util.regex.Matcher;
    import java.util.regex.Pattern;public class Test01 {    public static void main(String[] args) {
            
            // 子域名
            final String SUB_DOMAIN  = "(?i:[a-z0-9]|[a-z0-9][-a-z0-9]*[a-z0-9])";
            
            // 顶级域名
            final String TOP_DOMAINS = 
                                "(?x-i:com\\b        \n" +
                                "     |edu\\b        \n" +
                                "     |biz\\b        \n" +
                                "     |in(?:t|fo)\\b \n" +
                                "     |mil\\b        \n" +
                                "     |net\\b        \n" +
                                "     |org\\b        \n" +
                                "     |[a-z][a-z]\\b \n" + // 国家代码
                                ")                   \n";
            // 主机名
            final String HOSTNAME = "(?:" + SUB_DOMAIN + "\\.)+" + TOP_DOMAINS;
            
            // URL 地址中不允许包括的字符,以及其他的条件
            final String NOT_IN   = ";:\"'<>()\\[\\]{}\\s\\x7F-\\xFF";
            final String NOT_END  = "!.,?";
            final String ANYWHERE = "[^" + NOT_IN + NOT_END + "]";
            final String EMBEDDED = "[" + NOT_END + "]";
            final String URL_PATH = "/" + ANYWHERE + "*(" + EMBEDDED + "+" + ANYWHERE + "+)*";
            
            // 端口号 0~65535
            final String PORT = 
                "(?:                          \n" +
                "  [0-5]?[0-9]{1,4}           \n" +
                "  |                          \n" +
                "  6(?:                       \n" +
                "     [0-4][0-9]{3}           \n" +
                "     |                       \n" +
                "     5(?:                    \n" +
                "        [0-4][0-9]{2}        \n" +
                "        |                    \n" +
                "        5(?:                 \n" +
                "           [0-2][0-9]        \n" +
                "           |                 \n" +
                "           3[0-5]            \n" +
                "         )                   \n" +
                "      )                      \n" +
                "   )                         \n" +
                ")";
            
            // URL 表达式
            final String URL =
                "(?x:                                                \n"+
                "  \\b                                               \n"+
                "  (?:                                               \n"+
                "    (?: ftp | http s? ): // [-\\w]+(\\.\\w[-\\w]*)+ \n"+
                "   |                                                \n"+
                "    " + HOSTNAME + "                                \n"+
                "  )                                                 \n"+
                "  (?: : " + PORT + " )?                             \n"+
                "  (?: " + URL_PATH + ")?                            \n"+
                ")";
            
            // 测试代码
            String[] strs = {
                    "http://www.13.com",
                    "https://www.asdf.com.cn/asdf",
                    "www.23.com",
                    "http://www.123.com/tsf",
                    "http://www.abc.com/ab:2525/a.asp",
                    "http://www.123.com:2563/tsf/a.html?a=2&&b=abc",                
                    "http://www.aa.com/servlet",
                    "http://ee.com/abcSerlvet?a=8&&b=asdf",
                    "ftp://192.168.0.2:8080",
                    "http://ww.ss.com/////"                
                };
            
            Pattern pattern = Pattern.compile(URL);
            Matcher matcher = pattern.matcher("");
            for(int i = 0; i < strs.length; i++) {
                System.out.printf("%s --> %s%n", strs[i], matcher.reset(strs[i]).matches());
            }
        }
    }上面的表达式采用了内嵌的注释模式,用于书写调试期间使用,精简模式为(太长了,分成多行了):\b(?:(?:ftp|https?)://[-\w]+(\.\w[-\w]*)+|(?:(?i:[a-z0-9]|[a-z0-9][-a-z0-9]*[a-z0-9])\.)+
    (?x-i:com\b|edu\b|biz\b|in(?:t|fo)\b|mil\b|net\b|org\b|[a-z][a-z]\b))
    (?::(?:[0-5]?[0-9]{1,4}|6(?:[0-4][0-9]{3}|5(?:[0-4][0-9]{2}|5(?:[0-2][0-9]|3[0-5])))))?
    (?:/[^;:"'<>()\[\]{}\s\x7F-\xFF!.,?]*([!.,?]+[^;:"'<>()\[\]{}\s\x7F-\xFF!.,?]+)*)?
      

  15.   

    注释一下,上面的表达式中有一部分是直接引自 Mastering Regular Expressions 一书的。
      

  16.   

    经验证好像还不完善:http://www.qq.com/test/a.htmla.html这个它当作是合法的URL,不过有这个基础再改造应该很容易了,谢谢。
      

  17.   

    经过验证还发现以下问题:
        www.qq.com./,www.qq.com.,这样的是可以访问到腾讯主页的,因为最后面的“.”是根域名,是可以存在的,但在子域中可能不会出现。如
    www.qq.com./sports./abc.html这样的是不合法的。看来要完美几乎不太可能了,争取今天结贴。