用户可以输入文本,例如
This is some text, visit www.mysite.com. Thanks & bye.
应找到该URL并将其转换为链接,以便在网站中显示。所有其他字符应按原样显示。
我一直在搜索和谷歌搜索一段时间。我确信这种事情必定已经存在。我的诱惑是自己编程,但我确信这比它看起来更复杂。
我确信,一旦我尝试自己编程,我就会遇到其他问题。我不认为简单的reg-exp是前进的方向。
是否有任何库已经这样做了,理想情况下是Java? (如果它在另一种技术中,也许我可以看看它并将其转换为Java)
答案 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%可靠的检测。