当用户输入网址时,例如http://www.google.com
,我希望能够使用PHP解析该文本,查找任何链接,并将其替换为 {{ 1}}包含原始网址为<a>
的标记。
换句话说,HREF
将成为
http://www.google.com
我希望能够为这些表单的所有网址执行此操作(<a href="http://www.google.com">http://www.google.com</a>
可与任何TLD互换):
.com
最有效的方法是什么?我可以尝试写一些非常花哨的正则表达式,但我怀疑这是我可以使用的最佳方法。
对于奖励积分,我还希望将http://www.google.com
www.google.com
google.com
docs.google.com
添加到缺少它的任何网址,并将显示文本本身剥离为http://
形式的某些内容,然后显示外部链接图标。
答案 0 :(得分:1)
试图找到格式为domain.com的链接将是一个痛苦的屁股。它需要跟踪所有顶级域名并在搜索中使用它们。如果你没有输入我输入的最后一个句子的结尾,那么这句话的开头就是http://search.if的链接。即使你这样做.in是有效的TLD和常用词。
我建议告诉您的用户他们必须开始与www.
或http://
建立链接,然后编写一个简单的正则表达式来捕获它们并添加链接。
答案 1 :(得分:1)
www.google.com
这不是网址,而是主机名。在任意文本中开始标记裸主机名通常不是一个好主意,因为在一般情况下,点分隔词的任何单词或序列都是完全有效的主机名。这意味着您可能会遇到可疑的黑客,例如寻找领先的www.
(并且您会收到诸如“为什么我可以链接到www.stackoverflow.com
而不是stackoverflow.com
?”或“尾随TLD”的问题(随着更多新TLD的推出,越来越不切实际;“为什么我喜欢ncm.com但不喜欢ncm.museum
?”),而且你经常会标记那些不应该是链接的东西。< / p>
我可以尝试写一些非常花哨的正则表达式
好吧,我看不到你如何做没有正则表达式。
诀窍是应对标记。如果输入中包含<
,&
和"
个字符,则不得让它们进入HTML输出。如果您的输入是纯文本,则可以在对nico的答案中的模式应用简单替换之前调用htmlspecialchars()
来执行此操作。
(如果输入已包含标记,则表示您遇到问题,并且您可能需要一个HTML解析器来确定哪些位是标记,以避免在其中添加更多标记。同样,如果您在此之后进行更多处理插入更多标签,这些步骤可能会有同样的难度。在'bbcode'类语言中,这通常会导致错误和安全问题。)
另一个问题是落后标点符号。人们常常在链接后设置句号,逗号,右括号,感叹号等,这些链接不应该是链接的一部分,但实际上是有效字符。剥离它们并不将它们放在链接中是有用的。但是你打破了以)
结尾的Wiki链接,所以如果链接中有)
,或者类似的话,你可能不想将(
视为尾随字符。这种事情不能在简单的正则表达式替换中完成,但您可以在替换回调函数中完成。
答案 2 :(得分:1)
HTML Purifier有built-in linkify function可以帮助您解决所有问题。
如果您正在处理您还必须显示的任何类型的用户输入,那么其他功能也非常有用。
答案 3 :(得分:0)
不那么花哨的正则表达式
/\b(https?:\/\/[^\s+\"\<\>]+)/ig
/\b(www.[^\s+\"\<\>]+)/ig
请注意,最后两个是不可能正确完成的,因为你无法将google.com与这样的东西区分开来。我完成了一个句子并且在完全停止后没有放置空格。
至于缩短网址,将您的网址设为$url
:
if (strlen($url) > 20) // Or whatever length you like
{
$shortURL = substr($url, 0, 20)."…";
}
else
{
$shortURL = $url;
}
echo '<a href="'.$url.'" >'.$shortURL.'</a>';
答案 4 :(得分:0)
我按照我想要的方式完成了这项工作:
<?php
$input = <<<EOF
http://www.example.com/
http://example.com
www.example.com
http://iamanextremely.com/long/link/so/I/will/be/trimmed/down/a/bit/so/i/dont/mess
/up/text/wrapping.html
EOF;
function trimlong($match)
{
$url = $match[0];
$display = $url;
if ( strlen($display) > 30 ) {
$display = substr($display,0,30)."...";
}
return '<a href="'.$url.'">'.$display.' <img src="http://static.goalscdn.com/img/external-link.gif" height="10" width="11" /></a>';
}
$output = preg_replace_callback('#(http://|www\\.)[^\\s<]+[^\\s<,.]#i',
array($this,'trimlong'),$input);
echo $output;
答案 5 :(得分:0)
来自http://www.exorithm.com/algorithm/view/markup_urls
function markup_urls ($text)
{
// split the text into words
$words = preg_split('/([\s\n\r]+)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE);
$text = "";
// iterate through the words
foreach($words as $word) {
// chopword = the portion of the word that will be replaced
$chopword = $word;
$chopword = preg_replace('/^[^A-Za-z0-9]*/', '', $chopword);
if ($chopword <> '') {
// linkword = the text that will replace chopword in the word
$linkword='';
// does it start with http://abc. ?
if (preg_match('/^(http:\/\/)[a-zA-Z0-9_]{2,}.*/', $chopword)) {
$chopword = preg_replace('/[^A-Za-z0-9\/]*$/', '', $chopword);
$linkword = '<a href="'.$chopword.'" target="blank">'.$chopword.'</a>';
// does it equal abc.def.ghi ?
} else if (preg_match('/^[a-zA-Z]{2,}\.([a-zA-Z0-9_]+\.)+[a-zA-Z]{2,}(\/.*)?/', $chopword)) {
$chopword = preg_replace('/[^A-Za-z0-9\/]*$/', '', $chopword);
$linkword = '<a href="http://'.$chopword.'" target="blank">'.$chopword.'</a>';
// does it start with abc@def.ghi ?
} else if (preg_match('/^[a-zA-Z0-9_\.]+\@([a-zA-Z0-9_]{2,}\.)+[a-zA-Z]{2,}.*/', $chopword)) {
$chopword = preg_replace('/[^A-Za-z0-9]*$/', '', $chopword);
$linkword = '<a href="mailto:'.$chopword.'">'.$chopword.'</a>';
}
// replace chopword with linkword in word (if linkword was set)
if ($linkword <> '') {
$word = str_replace($chopword, $linkword, $word);
}
}
// append the word
$text = $text.$word;
}
return $text;
}