What's the best way to check if a String contains a URL in Java/Android?

前端 未结 10 1223
轮回少年
轮回少年 2020-12-02 21:18

What\'s the best way to check if a String contains a URL in Java/Android? Would the best way be to check if the string contains |.com | .net | .org | .info | .everythingelse

相关标签:
10条回答
  • 2020-12-02 21:18

    If you don't want to experiment with regular expressions and try a tested method, you can use the Apache Commons Library and validate if a given string is an URL/Hyperlink or not. Below is the example.

    Please note: This example is to detect if a given text as a 'whole' is a URL. For text that may contain a combination of regular text along with URLs, one might have to perform an additional step of splitting the string based on spaces and loop through the array and validate each array item.

    Gradle dependency:

    implementation 'commons-validator:commons-validator:1.6'
    

    Code:

    import org.apache.commons.validator.routines.UrlValidator;
    
    // Using the default constructor of UrlValidator class
    public boolean URLValidator(String s) {
        UrlValidator urlValidator = new UrlValidator();
        return urlValidator.isValid(s);
    }
    
    // Passing a scheme set to the constructor
    public boolean URLValidator(String s) {
        String[] schemes = {"http","https"}; // add 'ftp' is you need
        UrlValidator urlValidator = new UrlValidator(schemes);
        return urlValidator.isValid(s);
    }
    
    // Passing a Scheme set and set of Options to the constructor
    public boolean URLValidator(String s) {
        String[] schemes = {"http","https"}; // add 'ftp' is you need. Providing no Scheme will validate for http, https and ftp
        long options = UrlValidator.ALLOW_ALL_SCHEMES + UrlValidator.ALLOW_2_SLASHES + UrlValidator.NO_FRAGMENTS;
        UrlValidator urlValidator = new UrlValidator(schemes, options);
        return urlValidator.isValid(s);
    }
    
    // Possible Options are:
    // ALLOW_ALL_SCHEMES
    // ALLOW_2_SLASHES
    // NO_FRAGMENTS
    // ALLOW_LOCAL_URLS
    

    To use multiple options, just add them with the '+' operator

    If you need to exclude project level or transitive dependencies in the grade while using the Apache Commons library, you may want to do the following (Remove whatever is required from the list):

    implementation 'commons-validator:commons-validator:1.6' {
        exclude group: 'commons-logging'
        exclude group: 'commons-collections'
        exclude group: 'commons-digester'
        exclude group: 'commons-beanutils'
    }
    

    For more information, the link may provide some details.

    http://commons.apache.org/proper/commons-validator/dependencies.html

    0 讨论(0)
  • 2020-12-02 21:20

    Based on Enkk's answer, i present my solution:

    public static boolean containsLink(String input) {
        boolean result = false;
    
        String[] parts = input.split("\\s+");
    
        for (String item : parts) {
            if (android.util.Patterns.WEB_URL.matcher(item).matches()) {
                result = true;
                break;
            }
        }
    
        return result;
    }
    
    0 讨论(0)
  • 2020-12-02 21:23

    After looking around I tried to improve Zaid's answer by removing the try-catch block. Also, this solution recognizes more patterns as it uses a regex.

    So, firstly get this pattern:

    // Pattern for recognizing a URL, based off RFC 3986
    private static final Pattern urlPattern = Pattern.compile(
        "(?:^|[\\W])((ht|f)tp(s?):\\/\\/|www\\.)"
                + "(([\\w\\-]+\\.){1,}?([\\w\\-.~]+\\/?)*"
                + "[\\p{Alnum}.,%_=?&#\\-+()\\[\\]\\*$~@!:/{};']*)",
        Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
    

    Then, use this method (supposing str is your string):

        // separate input by spaces ( URLs don't have spaces )
        String [] parts = str.split("\\s+");
    
        // get every part
        for( String item : parts ) {
            if(urlPattern.matcher(item).matches()) { 
                //it's a good url
                System.out.print("<a href=\"" + item + "\">"+ item + "</a> " );                
            } else {
               // it isn't a url
                System.out.print(item + " ");    
            }
        }
    
    0 讨论(0)
  • 2020-12-02 21:23

    Old question, but found this, so I thought it might be useful to share. Should help for Android...

    0 讨论(0)
  • I would first use java.util.Scanner to find candidate URLs in the user input using a very dumb pattern that will yield false positives, but no false negatives. Then, use something like the answer @ZedScio provided to filter them down. For example,

    Pattern p = Pattern.compile("[^.]+[.][^.]+");
    Scanner scanner = new Scanner("Hey Dave, I found this great site called blah.com you should visit it");
    while (scanner.hasNext()) {
        if (scanner.hasNext(p)) {
            String possibleUrl = scanner.next(p);
            if (!possibleUrl.contains("://")) {
                possibleUrl = "http://" + possibleUrl;
            }
    
            try {
                URL url = new URL(possibleUrl);
                doSomethingWith(url);
            } catch (MalformedURLException e) {
                continue;
            }
        } else {
            scanner.next();
        }
    }
    
    0 讨论(0)
  • 2020-12-02 21:28

    You need to use URLUtil isNetworkUrl(url) or isValidUrl(url)

    0 讨论(0)
提交回复
热议问题