Biểu thức chính quy để khớp với các URL trong Java


86

Tôi sử dụng RegexBuddy trong khi làm việc với các biểu thức chính quy. Từ thư viện của nó, tôi đã sao chép biểu thức chính quy để khớp với các URL. Tôi đã thử nghiệm thành công trong RegexBuddy. Tuy nhiên, khi tôi sao chép nó dưới dạng Stringhương vị Java và dán nó vào mã Java, nó không hoạt động. Lớp sau in false:

public class RegexFoo {

    public static void main(String[] args) {
        String regex = "\\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|!:,.;]*[-A-Z0-9+&@#/%=~_|]";
        String text = "http://google.com";
        System.out.println(IsMatch(text,regex));
}

    private static boolean IsMatch(String s, String pattern) {
        try {
            Pattern patt = Pattern.compile(pattern);
            Matcher matcher = patt.matcher(s);
            return matcher.matches();
        } catch (RuntimeException e) {
        return false;
    }       
}   
}

Có ai biết tôi đang làm gì sai không?


4
Sergio, không bắt RuntimeException. Nó có thể tạo ra các lỗi nhỏ và nói chung là một thực tiễn xấu. Nếu bạn chỉ muốn bỏ qua tình huống khi biểu thức không hợp lệ, hãy sử dụng:} catch (PatternSyntaxException pse) {} để thay thế. Xem mục 57 của: java.sun.com/docs/books/effective
OscarRyz

Hoặc bạn có thể sử dụng Pattern patt = Pattern.compile (pattern, Pattern.CASE_INSENSITIVE); để tránh thay đổi regex để khớp với cả chữ hoa và chữ thường.
jm4

Tôi biết rằng điều này thực sự cũ ('08), nhưng đối với bất kỳ ai gặp vấn đề tương tự, RegexBuddy có tab "Sử dụng". Đảm bảo rằng bạn chọn hương vị Java 7 trước tiên, sau đó trong bảng "Sử dụng", bạn có thể để nó tạo mã Java cho trường hợp cụ thể của bạn. Điều này làm việc tốt cho tôi.
Daniel F

Câu trả lời:


106

Hãy thử chuỗi regex sau để thay thế. Thử nghiệm của bạn có thể đã được thực hiện theo cách phân biệt chữ hoa chữ thường. Tôi đã thêm các chữ cái viết thường alpha cũng như một trình giữ chỗ bắt đầu chuỗi thích hợp.

String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";

Điều này cũng hoạt động:

String regex = "\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";

Ghi chú:

String regex = "<\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>"; // matches <http://google.com>

String regex = "<^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>"; // does not match <http://google.com>

1
Sử dụng biểu thức chính quy của bạn, tôi cũng nhận được sai.
Sergio del Amo

Bạn có nắm bắt được chỉnh sửa cuối cùng của tôi. Tôi béo ngón tay vào đầu của chuỗi. Tôi vừa sao chép nó vào Eclipse và tôi nhận được "true".
TomC

1
nhờ người đàn ông, lần đầu tiên tôi thấy tiện ích để các ý kiến trong stackoverflow
Sergio del Amo

1
Không vấn đề gì. Nếu bạn đang sử dụng Eclipse, tôi thích sử dụng plugin RegEx Tester có sẵn tại đây brosinski.com/regex
TomC

thansk cho liên kết tôi đang sử dụng eclipse
Sergio del Amo

96

Cách tốt nhất để làm điều đó bây giờ là:

android.util.Patterns.WEB_URL.matcher(linkUrl).matches();

EDIT: Mã của Patternstừ https://github.com/android/platform_frameworks_base/blob/master/core/java/android/util/Patterns.java :

/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Commonly used regular expression patterns.
 */
public class Patterns {
    /**
     *  Regular expression to match all IANA top-level domains.
     *  List accurate as of 2011/07/18.  List taken from:
     *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
     *  This pattern is auto-generated by frameworks/ex/common/tools/make-iana-tld-pattern.py
     *
     *  @deprecated Due to the recent profileration of gTLDs, this API is
     *  expected to become out-of-date very quickly. Therefore it is now
     *  deprecated.
     */
    @Deprecated
    public static final String TOP_LEVEL_DOMAIN_STR =
        "((aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
        + "|(biz|b[abdefghijmnorstvwyz])"
        + "|(cat|com|coop|c[acdfghiklmnoruvxyz])"
        + "|d[ejkmoz]"
        + "|(edu|e[cegrstu])"
        + "|f[ijkmor]"
        + "|(gov|g[abdefghilmnpqrstuwy])"
        + "|h[kmnrtu]"
        + "|(info|int|i[delmnoqrst])"
        + "|(jobs|j[emop])"
        + "|k[eghimnprwyz]"
        + "|l[abcikrstuvy]"
        + "|(mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])"
        + "|(name|net|n[acefgilopruz])"
        + "|(org|om)"
        + "|(pro|p[aefghklmnrstwy])"
        + "|qa"
        + "|r[eosuw]"
        + "|s[abcdeghijklmnortuvyz]"
        + "|(tel|travel|t[cdfghjklmnoprtvwz])"
        + "|u[agksyz]"
        + "|v[aceginu]"
        + "|w[fs]"
        + "|(\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)"
        + "|y[et]"
        + "|z[amw])";

    /**
     *  Regular expression pattern to match all IANA top-level domains.
     *  @deprecated This API is deprecated. See {@link #TOP_LEVEL_DOMAIN_STR}.
     */
    @Deprecated
    public static final Pattern TOP_LEVEL_DOMAIN =
        Pattern.compile(TOP_LEVEL_DOMAIN_STR);

    /**
     *  Regular expression to match all IANA top-level domains for WEB_URL.
     *  List accurate as of 2011/07/18.  List taken from:
     *  http://data.iana.org/TLD/tlds-alpha-by-domain.txt
     *  This pattern is auto-generated by frameworks/ex/common/tools/make-iana-tld-pattern.py
     *
     *  @deprecated This API is deprecated. See {@link #TOP_LEVEL_DOMAIN_STR}.
     */
    @Deprecated
    public static final String TOP_LEVEL_DOMAIN_STR_FOR_WEB_URL =
        "(?:"
        + "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])"
        + "|(?:biz|b[abdefghijmnorstvwyz])"
        + "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])"
        + "|d[ejkmoz]"
        + "|(?:edu|e[cegrstu])"
        + "|f[ijkmor]"
        + "|(?:gov|g[abdefghilmnpqrstuwy])"
        + "|h[kmnrtu]"
        + "|(?:info|int|i[delmnoqrst])"
        + "|(?:jobs|j[emop])"
        + "|k[eghimnprwyz]"
        + "|l[abcikrstuvy]"
        + "|(?:mil|mobi|museum|m[acdeghklmnopqrstuvwxyz])"
        + "|(?:name|net|n[acefgilopruz])"
        + "|(?:org|om)"
        + "|(?:pro|p[aefghklmnrstwy])"
        + "|qa"
        + "|r[eosuw]"
        + "|s[abcdeghijklmnortuvyz]"
        + "|(?:tel|travel|t[cdfghjklmnoprtvwz])"
        + "|u[agksyz]"
        + "|v[aceginu]"
        + "|w[fs]"
        + "|(?:\u03b4\u03bf\u03ba\u03b9\u03bc\u03ae|\u0438\u0441\u043f\u044b\u0442\u0430\u043d\u0438\u0435|\u0440\u0444|\u0441\u0440\u0431|\u05d8\u05e2\u05e1\u05d8|\u0622\u0632\u0645\u0627\u06cc\u0634\u06cc|\u0625\u062e\u062a\u0628\u0627\u0631|\u0627\u0644\u0627\u0631\u062f\u0646|\u0627\u0644\u062c\u0632\u0627\u0626\u0631|\u0627\u0644\u0633\u0639\u0648\u062f\u064a\u0629|\u0627\u0644\u0645\u063a\u0631\u0628|\u0627\u0645\u0627\u0631\u0627\u062a|\u0628\u06be\u0627\u0631\u062a|\u062a\u0648\u0646\u0633|\u0633\u0648\u0631\u064a\u0629|\u0641\u0644\u0633\u0637\u064a\u0646|\u0642\u0637\u0631|\u0645\u0635\u0631|\u092a\u0930\u0940\u0915\u094d\u0937\u093e|\u092d\u093e\u0930\u0924|\u09ad\u09be\u09b0\u09a4|\u0a2d\u0a3e\u0a30\u0a24|\u0aad\u0abe\u0ab0\u0aa4|\u0b87\u0ba8\u0bcd\u0ba4\u0bbf\u0baf\u0bbe|\u0b87\u0bb2\u0b99\u0bcd\u0b95\u0bc8|\u0b9a\u0bbf\u0b99\u0bcd\u0b95\u0baa\u0bcd\u0baa\u0bc2\u0bb0\u0bcd|\u0baa\u0bb0\u0bbf\u0b9f\u0bcd\u0b9a\u0bc8|\u0c2d\u0c3e\u0c30\u0c24\u0c4d|\u0dbd\u0d82\u0d9a\u0dcf|\u0e44\u0e17\u0e22|\u30c6\u30b9\u30c8|\u4e2d\u56fd|\u4e2d\u570b|\u53f0\u6e7e|\u53f0\u7063|\u65b0\u52a0\u5761|\u6d4b\u8bd5|\u6e2c\u8a66|\u9999\u6e2f|\ud14c\uc2a4\ud2b8|\ud55c\uad6d|xn\\-\\-0zwm56d|xn\\-\\-11b5bs3a9aj6g|xn\\-\\-3e0b707e|xn\\-\\-45brj9c|xn\\-\\-80akhbyknj4f|xn\\-\\-90a3ac|xn\\-\\-9t4b11yi5a|xn\\-\\-clchc0ea0b2g2a9gcd|xn\\-\\-deba0ad|xn\\-\\-fiqs8s|xn\\-\\-fiqz9s|xn\\-\\-fpcrj9c3d|xn\\-\\-fzc2c9e2c|xn\\-\\-g6w251d|xn\\-\\-gecrj9c|xn\\-\\-h2brj9c|xn\\-\\-hgbk6aj7f53bba|xn\\-\\-hlcj6aya9esc7a|xn\\-\\-j6w193g|xn\\-\\-jxalpdlp|xn\\-\\-kgbechtv|xn\\-\\-kprw13d|xn\\-\\-kpry57d|xn\\-\\-lgbbat1ad8j|xn\\-\\-mgbaam7a8h|xn\\-\\-mgbayh7gpa|xn\\-\\-mgbbh1a71e|xn\\-\\-mgbc0a9azcg|xn\\-\\-mgberp4a5d4ar|xn\\-\\-o3cw4h|xn\\-\\-ogbpf8fl|xn\\-\\-p1ai|xn\\-\\-pgbs0dh|xn\\-\\-s9brj9c|xn\\-\\-wgbh1c|xn\\-\\-wgbl6a|xn\\-\\-xkc2al3hye2a|xn\\-\\-xkc2dl3a5ee0h|xn\\-\\-yfro4i67o|xn\\-\\-ygbi2ammx|xn\\-\\-zckzah|xxx)"
        + "|y[et]"
        + "|z[amw]))";

    /**
     * Good characters for Internationalized Resource Identifiers (IRI).
     * This comprises most common used Unicode characters allowed in IRI
     * as detailed in RFC 3987.
     * Specifically, those two byte Unicode characters are not included.
     */
    public static final String GOOD_IRI_CHAR =
        "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";

    public static final Pattern IP_ADDRESS
        = Pattern.compile(
            "((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]"
            + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]"
            + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}"
            + "|[1-9][0-9]|[0-9]))");

    /**
     * RFC 1035 Section 2.3.4 limits the labels to a maximum 63 octets.
     */
    private static final String IRI
        = "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}";

    private static final String GOOD_GTLD_CHAR =
        "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF";
    private static final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}";
    private static final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD;

    public static final Pattern DOMAIN_NAME
        = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")");

    /**
     *  Regular expression pattern to match most part of RFC 3987
     *  Internationalized URLs, aka IRIs.  Commonly used Unicode characters are
     *  added.
     */
    public static final Pattern WEB_URL = Pattern.compile(
        "((?:(http|https|Http|Https|rtsp|Rtsp):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)"
        + "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_"
        + "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?"
        + "(?:" + DOMAIN_NAME + ")"
        + "(?:\\:\\d{1,5})?)" // plus option port number
        + "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~"  // plus option query params
        + "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?"
        + "(?:\\b|$)"); // and finally, a word boundary or end of
                        // input.  This is to stop foo.sure from
                        // matching as foo.su

    public static final Pattern EMAIL_ADDRESS
        = Pattern.compile(
            "[a-zA-Z0-9\\+\\.\\_\\%\\-\\+]{1,256}" +
            "\\@" +
            "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,64}" +
            "(" +
                "\\." +
                "[a-zA-Z0-9][a-zA-Z0-9\\-]{0,25}" +
            ")+"
        );

    /**
     * This pattern is intended for searching for things that look like they
     * might be phone numbers in arbitrary text, not for validating whether
     * something is in fact a phone number.  It will miss many things that
     * are legitimate phone numbers.
     *
     * <p> The pattern matches the following:
     * <ul>
     * <li>Optionally, a + sign followed immediately by one or more digits. Spaces, dots, or dashes
     * may follow.
     * <li>Optionally, sets of digits in parentheses, separated by spaces, dots, or dashes.
     * <li>A string starting and ending with a digit, containing digits, spaces, dots, and/or dashes.
     * </ul>
     */
    public static final Pattern PHONE
        = Pattern.compile(                      // sdd = space, dot, or dash
                "(\\+[0-9]+[\\- \\.]*)?"        // +<digits><sdd>*
                + "(\\([0-9]+\\)[\\- \\.]*)?"   // (<digits>)<sdd>*
                + "([0-9][0-9\\- \\.]+[0-9])"); // <digit><digit|sdd>+<digit>

    /**
     *  Convenience method to take all of the non-null matching groups in a
     *  regex Matcher and return them as a concatenated string.
     *
     *  @param matcher      The Matcher object from which grouped text will
     *                      be extracted
     *
     *  @return             A String comprising all of the non-null matched
     *                      groups concatenated together
     */
    public static final String concatGroups(Matcher matcher) {
        StringBuilder b = new StringBuilder();
        final int numGroups = matcher.groupCount();

        for (int i = 1; i <= numGroups; i++) {
            String s = matcher.group(i);

            if (s != null) {
                b.append(s);
            }
        }

        return b.toString();
    }

    /**
     * Convenience method to return only the digits and plus signs
     * in the matching string.
     *
     * @param matcher      The Matcher object from which digits and plus will
     *                     be extracted
     *
     * @return             A String comprising all of the digits and plus in
     *                     the match
     */
    public static final String digitsAndPlusOnly(Matcher matcher) {
        StringBuilder buffer = new StringBuilder();
        String matchingRegion = matcher.group();

        for (int i = 0, size = matchingRegion.length(); i < size; i++) {
            char character = matchingRegion.charAt(i);

            if (character == '+' || Character.isDigit(character)) {
                buffer.append(character);
            }
        }
        return buffer.toString();
    }

    /**
     * Do not create this static utility class.
     */
    private Patterns() {}
}

3
+1 cho bạn! Cảm ơn bạn rất nhiều!!! Đây là mã tuyệt vời! Mọi người đang thử điều này với regex khó trong khi nó có thể dễ dàng như vậy. Tuyệt vời!
Kevin van Mierlo

7
@JPM Ngoại trừ việc OP đang tìm kiếm một giải pháp Java không phải một giải pháp dành riêng cho Android (dễ quên xem xét các thẻ cụ thể cho một Q). Tuy nhiên, một điều tốt cho những người làm mã cho Android biết về vì vậy tôi đã nâng cấp.
không thể chia cắt

3
@indivisible may mắn, Android là mã nguồn mở và bạn có thể lấy mã từ github.com/android/platform_frameworks_base/blob/master/core/... :)
EpicPandaForce

3
@EpicPandaForce Tôi nghĩ rằng nhận xét của bạn là điều duy nhất làm cho câu trả lời này có thể chấp nhận / hữu ích, như là câu hỏi đang tìm kiếm javagiải pháp, khôngandroid
Don Cheadle

1
nó không kiểm tra xem url bắt đầu từ http hay https. Tôi đã thử nghiệm với www.www và nó đã cho tôi sự thật. Vì vậy, không hữu ích cho tôi
FaisalAhmed

74

Tôi sẽ thử một tiêu chuẩn "Tại sao bạn làm theo cách này?" câu trả lời ... Bạn có biết về java.net.URL?

URL url = new URL(stringURL);

Ở trên sẽ ném ra một MalformedURLExceptionnếu nó không thể phân tích cú pháp URL.


1
Tôi phải đi qua con đường biểu thức chính quy. Những gì tôi đăng ở đây càng đơn giản càng tốt để làm rõ câu hỏi của tôi. Trong chương trình của mình, tôi đang sử dụng URL regex bên trong một regex phức tạp hơn.
Sergio del Amo

Thật tuyệt. Tôi không có câu trả lời nào tốt hơn một cách khôn ngoan, vì vậy tôi nghĩ tôi sẽ đăng một câu trả lời thay thế. Tuy nhiên, tôi không nghĩ rằng tôi sẽ bị đánh giá thấp vì nó.
billjamesdev

2
bạn nói đúng, có lẽ đã bị đánh giá thấp hơn một chút. "Tôi sẽ thử tiêu chuẩn" nghe có vẻ hơi khó chịu.
Sergio del Amo

cool (xin lỗi, kỳ nghỉ nhanh). Ya, chắc chắn không có ý định như vậy. Tôi chỉ thấy rằng rất nhiều ở đây, và đôi khi nó thậm chí còn hữu ích.
billjamesdev 6/10/08

14
"URL mới" chỉ ném MalformedURLException nếu cổng <0 hoặc cổng không hiểu giao thức. Ngoài ra, bất cứ điều gì đi. Nó sẽ không bắt được: 1.2.3. 1.2.3.4.5 1.2,3.4.5 : vv
David Newcomb

4

Vấn đề với tất cả các cách tiếp cận được đề xuất: tất cả RegEx đang xác thực

Tất cả mã dựa trên RegEx đều được thiết kế kỹ lưỡng: nó sẽ chỉ tìm thấy các URL hợp lệ! Là một mẫu, nó sẽ bỏ qua bất kỳ thứ gì bắt đầu bằng "http: //" và có các ký tự không phải ASCII bên trong.

Thậm chí nhiều hơn: Tôi đã gặp phải thời gian xử lý 1-2 giây (đơn luồng, chuyên dụng) với gói Java RegEx (lọc địa chỉ Email khỏi văn bản) cho các câu rất nhỏ và đơn giản, không có gì cụ thể; có thể lỗi trong Java 6 RegEx ...

Giải pháp đơn giản nhất / nhanh nhất sẽ là sử dụng StringTokenizer để chia văn bản thành các mã thông báo, loại bỏ các mã thông báo bắt đầu bằng "http: //", v.v. và nối các mã thông báo vào văn bản một lần nữa.

Nếu bạn muốn lọc Email khỏi văn bản (vì sau này bạn sẽ làm nhân viên NLP, v.v.) - chỉ cần loại bỏ tất cả các mã thông báo có chứa "@" bên trong.

Đây là văn bản đơn giản mà RegEx của Java 6 không thành công. Hãy thử nó trong các biến thể khác nhau của Java. Mất khoảng 1000 mili giây cho mỗi cuộc gọi RegEx, trong một ứng dụng kiểm tra luồng đơn đang chạy lâu dài:

pattern = Pattern.compile("[A-Za-z0-9](([_\\.\\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\\.\\-]?[a-zA-Z0-9]+)*)\\.([A-Za-z]{2,})", Pattern.CASE_INSENSITIVE);

"Avalanna is such a sweet little girl! It would b heartbreaking if cancer won. She's so precious! #BeliebersPrayForAvalanna");
"@AndySamuels31 Hahahahahahahahahhaha lol, you don't look like a girl hahahahhaahaha, you are... sexy.";

Không dựa vào cụm từ thông dụng nếu bạn chỉ cần lọc các từ có "@", "http: //", "ftp: //", "mailto:"; nó là chi phí kỹ thuật rất lớn.

Nếu bạn thực sự muốn sử dụng RegEx với Java, hãy thử Automaton


Cười lớn. Automaton không hỗ trợ nhóm nắm bắt.
user1050755

4
Tôi không nhận được sự quan tâm của bạn. Thực tế, regex của câu trả lời được chấp nhận hoạt động tốt để xác thực URL. Bạn dường như bắt nguồn từ nó, nói rằng it will find only valid URLs!- đó là mục tiêu của câu hỏi của OP. Tui bỏ lỡ điều gì vậy?
Don Cheadle

3

Phù hợp với câu trả lời billjamesdev, đây là một cách tiếp cận khác để xác thực URL mà không cần sử dụng RegEx:

Từ Apache Commons Validator lib, hãy xem lớp UrlValidator . Một số mã ví dụ:

Tạo một UrlValidator với các lược đồ hợp lệ là "http" và "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"

Nếu thay vào đó, hàm tạo mặc định được sử dụng.

UrlValidator urlValidator = new UrlValidator();
if (urlValidator.isValid("ftp://foo.bar.com/")) {
   System.out.println("url is valid");
} else {
   System.out.println("url is invalid");
}

in ra "url hợp lệ"


2

Điều này cũng hoạt động:

String regex = "\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";

Ghi chú:

String regex = "<\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>"; // matches <http://google.com>

String regex = "<^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]>"; // does not match <http://google.com>

Vì vậy, có lẽ cái đầu tiên hữu ích hơn cho việc sử dụng chung.


1
((http?|https|ftp|file)://)?((W|w){3}.)?[a-zA-Z0-9]+\.[a-zA-Z]+

kiểm tra ở đây: - https://www.freeformatter.com/java-regex-tester.html#ad-output

Nó sắp xếp các mục nhập luận văn một cách chính xác


Nó không cho các ký tự đặc biệt
Sankalp Kotewar

tôi cần regex để xóa url khỏi tên bài hát. Couldnt tìm thấy một hoặc tôi nên nói không thành công nhất vì vậy tôi đăng tải những gì làm việc cho tôi và những trường hợp đó :)
Abhiraj

đúng vậy. kiểm tra nó trên liên kết được cung cấp.
Abhiraj

0

Khi sử dụng các biểu thức chính quy từ thư viện của RegexBuddy, hãy đảm bảo sử dụng các chế độ đối sánh tương tự trong mã của riêng bạn như regex từ thư viện. Nếu bạn tạo đoạn mã nguồn trên tab Sử dụng, RegexBuddy sẽ tự động đặt các tùy chọn đối sánh chính xác trong đoạn mã nguồn. Nếu bạn sao chép / dán regex, bạn phải tự làm điều đó.

Trong trường hợp này, như những người khác đã chỉ ra, bạn đã bỏ qua tùy chọn phân biệt chữ hoa chữ thường.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.