URL自动检测和文本块中的突出显示

时间:2011-11-07 10:58:37

标签: java

用户可以输入文本,例如

This is some text, visit www.mysite.com. Thanks & bye.

应找到该URL并将其转换为链接,以便在网站中显示。所有其他字符应按原样显示。

我一直在搜索和谷歌搜索一段时间。我确信这种事情必定已经存在。我的诱惑是自己编程,但我确信这比它看起来更复杂。

  • 点可以是URL的一部分,也可以是上面的句子终止符。我认为用户期望这将得到妥善处理;例如,Outlook正确处理此问题。
  • 有各种不同的协议,例如http:,https:等,如上所述,通常在没有协议说明符的情况下输入链接。
  • 必须生成HTML(以便可以插入&lt; a ...&gt;标签),因此有必要更换例如: &安培;与&amp; amp; amp;在做之前;但有些网址有&amp;在它们中(例如xyz.cgi?a = b&amp; c = d),我们只需要一个&amp; amp; amp;插入URL的可显示部分而不是链接本身(&lt; a href =“...&amp; ...”&gt; ...&amp; amp; ...&lt; / a&gt;)< / LI>

我确信,一旦我尝试自己编程,我就会遇到其他问题。我不认为简单的reg-exp是前进的方向。

是否有任何库已经这样做了,理想情况下是Java? (如果它在另一种技术中,也许我可以看看它并将其转换为Java)

2 个答案:

答案 0 :(得分:1)

虽然你是对的,这是一个普遍的问题,但它也是一个在任何地方都没有真正令人满意地解决的问题,也不是。没有用像这样的自由文本写的标记的URI可能是不明确的(例如,参见http://en.wikisource.org/wiki/1911_Encyclop%C3%A6dia_Britannica/Aga_Khan_I.,你怎么知道'。'不是句号的“句尾”句号,实际上是URI的一部分?) 。您可以查看the problem with urls以了解问题的介绍,并在评论中进行详尽的讨论。在一天结束时,您可以提供最佳工作,例如匹配协议,寻找有效的顶级域名(包括a lot more,而不是您最初想到的),但总会有一些事情在网络中滑落

为了尝试为您提供一些伪代码,我会说这些内容是我开始使用的内容:

process() {
    List<String> looksLikeUri = getMatches(1orMoreValidUriCharacters + "\\." + 1orMoreValidUriCharacters);
    removeUrisWithInvalidTopLevelDomains(looksLikeUri);
    trimCharactersUnlikelyToBeInUris(looksLikeUri);
    guessProtocolIfNotPresent(looksLikeUri);
}

removeUrisWithInvalidTopLevelDomains() // Use a list of valid ones or limit it to something like 1-6 characters.

trimCharactersUnlikelyToBeInUris() // ,.:;? (at the very end) '(' at start ')' at end unless a starting one was in URI.

guessProtocolIfNotPresent() // Usually http unless string starts with something obvious like "ftp" or already has a protocol.

答案 1 :(得分:0)

如果包含的URL始终包含协议(例如HTTP),那么它可能是完全可解的。 因为事实并非如此,任何“单词”,其中包含。字符可能是URL(例如mysite.com),而且你不能确定实际的协议(你可以假设)。

如果您认为该用户将始终在线,您可以创建一个方法来获取所有可能的URL,检查URL是否存在以及是否存在,然后生成HTML链接。

我已经编写了这段代码:

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.regex.*;


public class JavaURLHighlighter
{
    Pattern potentialURLAtTheBeginning = Pattern.compile("^[^\\s]+\\.[^\\s]+\\s");
    Pattern potentialURLintheMiddle = Pattern.compile("\\s[^\\s]+\\.[^\\s]+\\s");
    Pattern potentialURLAtTheEnd = Pattern.compile("\\s[^\\s]+\\.[^\\s]+$");
    private String urlString;
    ArrayList<String> matchesList=new ArrayList<String>();

    public String getUrlString() {
        return urlString;
    }

    public void setUrlString(String urlString) {
        this.urlString = urlString;
    }

    public void getConvertedMatches()
     {
        String match;
        String originalMatch;
        Matcher matcher;
        matcher = potentialURLAtTheBeginning.matcher(urlString);
        matchesList.clear();
        while (matcher.find())
        {
          match = matcher.group().trim();
          if (!match.startsWith("http://") && !match.startsWith("https://")) match = "http://"+match;
          if (match.endsWith(".")) match=match.substring(0, match.length()-1);
          if (urlExists(match)) matchesList.add(match);
        }
        matcher = potentialURLintheMiddle.matcher(urlString);
        while (matcher.find()) 
        {
          match = matcher.group().trim();
          if (!match.startsWith("http://") && !match.startsWith("https://")) match = "http://"+match;
          if (match.endsWith(".")) match=match.substring(0, match.length()-1);
          if (urlExists(match))matchesList.add(match);
        }
        matcher = potentialURLAtTheEnd.matcher(urlString);
        while (matcher.find()) 
        {
          match = matcher.group().trim();
          if (!match.startsWith("http://") && !match.startsWith("https://")) match = "http://"+match;
          if (match.endsWith(".")) match=match.substring(0, match.length()-1);
          if (urlExists(match)) matchesList.add(match);
        }

        for (int i=0; i< matchesList.size();i++) System.out.println(matchesList.get(i));
    }

    public static boolean urlExists(String urlAddress)
    {
        try
        {
          HttpURLConnection.setFollowRedirects(false);
          HttpURLConnection connection = (HttpURLConnection) new URL(urlAddress).openConnection();
          connection.setRequestMethod("HEAD");
          return (connection.getResponseCode() == HttpURLConnection.HTTP_OK);
        }
        catch (Exception e)  {return false;  }
    }

public static void main(String[] args)
{
    JavaURLHighlighter hg = new JavaURLHighlighter();

    hg.setUrlString("This is some text, visit www.mysite.com. Thanks & bye.");
    hg.getConvertedMatches();

    hg.setUrlString("This is some text, visit www.nonexistingmysite.com. Thanks & bye.");
    hg.getConvertedMatches();    

}

}

这不是你的问题的实际解决方案,我写得很快,所以它可能不完全正确,但它应该指导你一点。我在这里打印比赛。看看这里Java equivalent to PHP's preg_replace_callback的regexp替换函数,你可以用hrefs包含所有修改过的匹配。使用提供的信息,您应该能够写出您想要的内容 - 但可能没有100%可靠的检测。