【问题标题】:What's the best way to check if a String contains a URL in Java/Android?检查字符串是否包含 Java/Android 中的 URL 的最佳方法是什么?
【发布时间】:2012-06-15 22:42:29
【问题描述】:

在 Java/Android 中检查字符串是否包含 URL 的最佳方法是什么?最好的方法是检查字符串是否包含 |.com | .net | .org | .info | .一切|?还是有更好的方法?

该 url 在 Android 中输入到 EditText 中,它可以是粘贴的 url,也可以是手动输入的 url,用户不想输入 http://... 我正在研究网址缩短应用。

【问题讨论】:

  • 您期望什么样的 URL?相对 URL 很难检测。 / 字符是一种方式,但往往会误报。
  • 总是以协议开头吗?你能试着用URL解析它吗?
  • 一旦新的GTLDs 出现,祝你好运;)
  • @WilliamL。 : 你没有提供足够的信息。当你说“如果一个字符串包含一个 URL”时,如何......“嘿,戴夫,我发现了这个名为 blah.com 的很棒的网站,你应该访问它”?我的意思是你的弦是从哪里来的?在这种情况下,blah.com 可能是一个有效的 URL,但您是在解析任何通用文本还是......好吧,无论如何。你的问题很模糊。正如 Dave Newton 建议的那样,URL 类(和 URI 类)可用于解析。
  • 任何以 .com 或 .anything 结尾的东西都不必以 http:// 开头。@Squonk 我更新了我的答案

标签: java android string


【解决方案1】:

最好的方法是使用正则表达式,如下所示:

public static final String URL_REGEX = "^((https?|ftp)://|(www|ftp)\\.)?[a-z0-9-]+(\\.[a-z0-9-]+)+([/?].*)?$";

Pattern p = Pattern.compile(URL_REGEX);
Matcher m = p.matcher("example.com");//replace with string to compare
if(m.find()) {
    System.out.println("String contains URL");
}

【讨论】:

  • 已解决!最准确和可接受的答案!谢谢!
  • 这不起作用。对于文本hehe, check this link: http://www.example.com/ m.find() 返回 false
  • 对于任何字符串,如 [a-z0-9.][a-z0-9],它都会返回 true。所以“asdj.asdj”将是积极的
【解决方案2】:

这只是通过在构造函数周围的 try catch 来完成的(无论哪种方式都是必要的)。

String inputUrl = getInput();
if (!inputUrl.contains("http://"))
    inputUrl = "http://" + inputUrl;

URL url;
try {
    url = new URL(inputUrl);
} catch (MalformedURLException e) {
    Log.v("myApp", "bad url entered");
}
if (url == null)
    userEnteredBadUrl();
else
    continue();

【讨论】:

  • 了解 Java 的工作原理,但在 .NET 中我尝试了类似的方法。这个解决方案似乎并不可靠。将 http:// 附加到任何内容都会为我返回一个有效的 URI。也许几乎任何前面带有 http:// 的东西都是有效的。大声笑。
【解决方案3】:

环顾四周后,我试图通过删除 try-catch 块来改进 Zaid 的答案。此外,此解决方案使用正则表达式可识别更多模式。

所以,首先得到这个模式:

// 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);

然后,使用这个方法(假设str是你的字符串):

    // 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 + " ");    
        }
    }

【讨论】:

  • 这不能识别链接“example.com”,但是按空格分割字符串然后检查的想法很棒。只需稍微调整正则表达式即可达到完美。编辑:代替您提供的正则表达式,可以像这样使用 android.util.Patterns.WEB_URL:android.util.Patterns.WEB_URL.matcher("example.com").matches();
【解决方案4】:

根据 Enkk 的回答,我提出我的解决方案:

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;
}

【讨论】:

    【解决方案5】:

    老问题,但找到this,所以我认为分享一下可能有用。应该对 Android 有所帮助...

    【讨论】:

      【解决方案6】:

      我将首先使用 java.util.Scanner 在用户输入中查找候选 URL,使用一种非常愚蠢的模式,该模式会产生误报,但不会产生误报。然后,使用类似于@ZedScio 提供的答案来过滤它们。例如,

      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();
          }
      }
      

      【讨论】:

      • 我认为这是我想要的,但它适用于所有网址吗?包括文件和ftp!让我检查一下它是如何工作的。无论如何,谢谢。
      【解决方案7】:

      如果您不想尝试正则表达式并尝试测试方法,您可以使用 Apache Commons Library 并验证给定字符串是否为 URL/超链接。下面是例子。

      请注意:此示例用于检测给定文本作为“整体”是否为 URL。对于可能包含常规文本和 URL 组合的文本,可能必须执行额外的步骤,即根据空格拆分字符串并循环遍历数组并验证每个数组项。

      Gradle 依赖:

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

      代码:

      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
      

      要使用多个选项,只需使用“+”运算符添加它们

      如果您在使用 Apache Commons 库时需要在成绩中排除项目级别或传递依赖项,您可能需要执行以下操作(从列表中删除所需的任何内容):

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

      有关更多信息,该链接可能会提供一些详细信息。

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

      【讨论】:

        【解决方案8】:

        你需要使用URLUtilisNetworkUrl(url)或isValidUrl(url)

        【讨论】:

          【解决方案9】:
          public boolean isURL(String text) {
              return text.length() > 3 && text.contains(".")
                      && text.toCharArray()[text.length() - 1] != '.' && text.toCharArray()[text.length() - 2] != '.'
                      && !text.contains(" ") && !text.contains("\n");
          }
          

          【讨论】:

            【解决方案10】:

            这个功能对我有用

            private boolean containsURL(String content){
                String REGEX = "\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
                Pattern p = Pattern.compile(REGEX,Pattern.CASE_INSENSITIVE);
                Matcher m = p.matcher(content);
                return m.find();
            }
            

            调用这个函数

            boolean isContain = containsURL("Pass your string here...");
            Log.d("Result", String.valueOf(isContain));
            

            注意:- 我已经测试了包含单个 url 的字符串

            【讨论】:

              【解决方案11】:

              最好的方法是设置属性自动链接到您的文本视图,Android 将识别、更改外观并使可点击的链接成为字符串内的任何位置。

              android:autoLink="web"

              【讨论】:

              • 你已经回答了一些你自己编造的问题
              猜你喜欢
              • 2014-12-20
              • 1970-01-01
              • 2011-07-04
              • 2014-12-20
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-05-25
              • 2012-03-28
              相关资源
              最近更新 更多