我有一个简单的评论系统,人们可以在纯文本字段中提交超链接。当我将这些记录从数据库显示到网页中时,我可以使用 PHP 中的什么 RegExp 将这些链接转换为 HTML 类型的锚链接?
我不希望算法使用任何其他类型的链接来做到这一点,只是 http 和 https。
我有一个简单的评论系统,人们可以在纯文本字段中提交超链接。当我将这些记录从数据库显示到网页中时,我可以使用 PHP 中的什么 RegExp 将这些链接转换为 HTML 类型的锚链接?
我不希望算法使用任何其他类型的链接来做到这一点,只是 http 和 https。
这是另一种解决方案,这将捕获所有 http/https/www 并转换为可点击的链接。
$url = '~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i';
$string = preg_replace($url, '<a href="$0" target="_blank" title="$0">$0</a>', $string);
echo $string;
或者,如果只是捕获 http/https,请使用下面的代码。
$url = '/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(\/\S*)?/';
$string= preg_replace($url, '<a href="$0" target="_blank" title="$0">$0</a>', $string);
echo $string;
编辑:下面的脚本将捕获所有 URL 类型并将它们转换为可点击的链接。
$url = '@(http)?(s)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@';
$string = preg_replace($url, '<a href="http$2://$4" target="_blank" title="$0">$0</a>', $string);
echo $string;
新的更新,如果你有字符串剥离 (s) 然后使用下面的代码块,感谢@AndrewEllis 指出这一点。
$url = '@(http(s)?)?(://)?(([a-zA-Z])([-\w]+\.)+([^\s\.]+[^\s]*)+[^,.\s])@';
$string = preg_replace($url, '<a href="http$2://$4" target="_blank" title="$0">$0</a>', $string);
echo $string;
这是 URL 无法正确显示的一个非常简单的解决方案。
$email = '<a href="mailto:email@email.com">email@email.com</a>';
$string = $email;
echo $string;
这是一个非常简单的修复,但您必须根据自己的目的对其进行修改。
我提供了多个答案,因为某些服务器的设置不同,所以一个答案可能适用于某些人但不适用于其他人,但我希望答案对你有用,如果没有,请告诉我,希望我能想出另一个解决方案。
有多个脚本,因为有些 PHP 文件需要不同的脚本,有些服务器的设置也不同,另外每个都有不同的要求,有些只需要 HTTP/S,有些只需要 WWW,有些需要 FTP/S,每个都将取决于如何工作设置了用户自己的脚本,我为每个脚本提供了一些文本,说明了他们所做的事情。
好吧,Volomike 的答案更接近。为了更进一步,这就是我所做的,它忽略了超链接末尾的尾随句点。我还考虑了 URI 片段。
public static function makeClickableLinks($s) {
return preg_replace('@(https?://([-\w\.]+[-\w])+(:\d+)?(/([\w/_\.#-]*(\?\S+)?[^\.\s])?)?)@', '<a href="$1" target="_blank">$1</a>', $s);
}
请参阅http://zenverse.net/php-function-to-auto-convert-url-into-hyperlink/。这就是wordpress如何解决它
function _make_url_clickable_cb($matches) {
$ret = '';
$url = $matches[2];
if ( empty($url) )
return $matches[0];
// removed trailing [.,;:] from URL
if ( in_array(substr($url, -1), array('.', ',', ';', ':')) === true ) {
$ret = substr($url, -1);
$url = substr($url, 0, strlen($url)-1);
}
return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>" . $ret;
}
function _make_web_ftp_clickable_cb($matches) {
$ret = '';
$dest = $matches[2];
$dest = 'http://' . $dest;
if ( empty($dest) )
return $matches[0];
// removed trailing [,;:] from URL
if ( in_array(substr($dest, -1), array('.', ',', ';', ':')) === true ) {
$ret = substr($dest, -1);
$dest = substr($dest, 0, strlen($dest)-1);
}
return $matches[1] . "<a href=\"$dest\" rel=\"nofollow\">$dest</a>" . $ret;
}
function _make_email_clickable_cb($matches) {
$email = $matches[2] . '@' . $matches[3];
return $matches[1] . "<a href=\"mailto:$email\">$email</a>";
}
function make_clickable($ret) {
$ret = ' ' . $ret;
// in testing, using arrays here was found to be faster
$ret = preg_replace_callback('#([\s>])([\w]+?://[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_url_clickable_cb', $ret);
$ret = preg_replace_callback('#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]*)#is', '_make_web_ftp_clickable_cb', $ret);
$ret = preg_replace_callback('#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret);
// this one is not in an array because we need it to run last, for cleanup of accidental links within links
$ret = preg_replace("#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i", "$1$3</a>", $ret);
$ret = trim($ret);
return $ret;
}
<?
function makeClickableLinks($text)
{
$text = html_entity_decode($text);
$text = " ".$text;
$text = eregi_replace('(((f|ht){1}tp://)[-a-zA-Z0-9@:%_\+.~#?&//=]+)',
'<a href="\\1" target=_blank>\\1</a>', $text);
$text = eregi_replace('(((f|ht){1}tps://)[-a-zA-Z0-9@:%_\+.~#?&//=]+)',
'<a href="\\1" target=_blank>\\1</a>', $text);
$text = eregi_replace('([[:space:]()[{}])(www.[-a-zA-Z0-9@:%_\+.~#?&//=]+)',
'\\1<a href="http://\\2" target=_blank>\\2</a>', $text);
$text = eregi_replace('([_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3})',
'<a href="mailto:\\1" target=_blank>\\1</a>', $text);
return $text;
}
// Example Usage
echo makeClickableLinks("This is a test clickable link: http://www.websewak.com You can also try using an email address like test@websewak.com");
?>
评分最高的答案对我没有用,以下链接未正确替换:
http://www.fifa.com/worldcup/matches/round255951/match=300186487/index.html#nosticky
经过一些谷歌搜索和一些测试,这就是我想出的:
public static function replaceLinks($s) {
return preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.%-=#]*(\?\S+)?)?)?)@', '<a href="$1">$1</a>', $s);
}
我不是正则表达式的专家,实际上它让我很困惑:)
因此,请随时评论并改进此解决方案。
这是我的代码,用于格式化文本中的所有链接,包括电子邮件、带有和不带有协议的 url。
public function formatLinksInText($text)
{
//Catch all links with protocol
$reg = '/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(\/\S*)?/';
$formatText = preg_replace($reg, '<a href="$0" style="font-weight: normal;" target="_blank" title="$0">$0</a>', $text);
//Catch all links without protocol
$reg2 = '/(?<=\s|\A)([0-9a-zA-Z\-\.]+\.[a-zA-Z0-9\/]{2,})(?=\s|$|\,|\.)/';
$formatText = preg_replace($reg2, '<a href="//$0" style="font-weight: normal;" target="_blank" title="$0">$0</a>', $formatText);
//Catch all emails
$emailRegex = '/(\S+\@\S+\.\S+)\b/';
$formatText = preg_replace($emailRegex, '<a href="mailto:$1" style="font-weight: normal;" target="_blank" title="$1">$1</a>', $formatText);
$formatText = nl2br($formatText);
return $formatText;
}
请评论不起作用的网址。我会尝试更新正则表达式。
MkVal 的答案有效,但如果我们已经有了锚链接,它将以奇怪的格式呈现文本。
这是在这两种情况下都适用于我的解决方案:
$s = preg_replace (
"/(?<!a href=\")(?<!src=\")((http|ftp)+(s)?:\/\/[^<>\s]+)/i",
"<a href=\"\\0\" target=\"blank\">\\0</a>",
$s
);
public static function makeClickableLinks($s) {
return preg_replace('@(https?://([-\w\.]+)+(:\d+)?(/([\w/_\.-]*(\?\S+)?)?)?)@', '<a href="$1">$1</a>', $s);
}
我建议不要像这样在飞行中做很多事情。我更喜欢使用简单的编辑器界面,比如 stackoverflow 中使用的界面。它被称为降价。
我正在使用一个源自question2answer的函数,它接受纯文本甚至 html 中的纯文本链接:
// $html holds the string
$htmlunlinkeds = array_reverse(preg_split('|<[Aa]\s+[^>]+>.*</[Aa]\s*>|', $html, -1, PREG_SPLIT_OFFSET_CAPTURE)); // start from end so we substitute correctly
foreach ($htmlunlinkeds as $htmlunlinked)
{ // and that we don't detect links inside HTML, e.g. <img src="http://...">
$thishtmluntaggeds = array_reverse(preg_split('/<[^>]*>/', $htmlunlinked[0], -1, PREG_SPLIT_OFFSET_CAPTURE)); // again, start from end
foreach ($thishtmluntaggeds as $thishtmluntagged)
{
$innerhtml = $thishtmluntagged[0];
if(is_numeric(strpos($innerhtml, '://')))
{ // quick test first
$newhtml = qa_html_convert_urls($innerhtml, qa_opt('links_in_new_window'));
$html = substr_replace($html, $newhtml, $htmlunlinked[1]+$thishtmluntagged[1], strlen($innerhtml));
}
}
}
echo $html;
function qa_html_convert_urls($html, $newwindow = false)
/*
Return $html with any URLs converted into links (with nofollow and in a new window if $newwindow).
Closing parentheses/brackets are removed from the link if they don't have a matching opening one. This avoids creating
incorrect URLs from (http://www.question2answer.org) but allow URLs such as http://www.wikipedia.org/Computers_(Software)
*/
{
$uc = 'a-z\x{00a1}-\x{ffff}';
$url_regex = '#\b((?:https?|ftp)://(?:[0-9'.$uc.'][0-9'.$uc.'-]*\.)+['.$uc.']{2,}(?::\d{2,5})?(?:/(?:[^\s<>]*[^\s<>\.])?)?)#iu';
// get matches and their positions
if (preg_match_all($url_regex, $html, $matches, PREG_OFFSET_CAPTURE)) {
$brackets = array(
')' => '(',
'}' => '{',
']' => '[',
);
// loop backwards so we substitute correctly
for ($i = count($matches[1])-1; $i >= 0; $i--) {
$match = $matches[1][$i];
$text_url = $match[0];
$removed = '';
$lastch = substr($text_url, -1);
// exclude bracket from link if no matching bracket
while (array_key_exists($lastch, $brackets)) {
$open_char = $brackets[$lastch];
$num_open = substr_count($text_url, $open_char);
$num_close = substr_count($text_url, $lastch);
if ($num_close == $num_open + 1) {
$text_url = substr($text_url, 0, -1);
$removed = $lastch . $removed;
$lastch = substr($text_url, -1);
}
else
break;
}
$target = $newwindow ? ' target="_blank"' : '';
$replace = '<a href="' . $text_url . '" rel="nofollow"' . $target . '>' . $text_url . '</a>' . $removed;
$html = substr_replace($html, $replace, $match[1], strlen($match[0]));
}
}
return $html;
}
由于接受包含括号和其他字符的链接,所以代码有点多,但它可能会有所帮助。
试试这个:
$s = preg_replace('/(?<!href="|">)(?<!src=\")((http|ftp)+(s)?:\/\/[^<>\s]+)/is', '<a href="\\1" target="_blank">\\1</a>', $s);
它跳过现有的链接(如果我们已经有一个 href,它不会在一个 href 中添加一个 href)。否则它将添加带有空白目标的 a href。
我真的很喜欢这个答案——但我需要一个解决方案来解决非常简单的 HTML 文本中可能存在的纯文本链接:
<p>I found a really cool site you might like:</p>
<p>www.stackoverflow.com</p>
这意味着我需要正则表达式模式来忽略 html 字符<
和>
所以我将部分模式[^\s\>\<]
改为\S
\S
- 不是空白;匹配任何非空白字符(制表符、空格、换行符)[^]
- 一个否定集;匹配任何不在集合中的字符除了 HTML 之外,我还需要另一种格式,因此我将正则表达式从它们的替换中分离出来以适应这种情况。
我还添加了一种仅将找到的链接/电子邮件返回到数组中的方法,这样我就可以将它们保存为我的帖子中的关系(非常适合以后为它们制作元卡......以及用于分析!)。
我得到了类似文本的匹配there...it
- 所以我想确保我没有得到任何包含连续点的匹配。
注意:为了解决这个问题,我添加了一个额外的格式字符串来撤消匹配它们,以避免不得不重做这些原本可靠的 url 正则表达式。
/***
* based on this answer: https://stackoverflow.com/a/49689245/2100636
*
* @var $text String
* @var $format String - html (<a href=""...), short ([link:https://somewhere]), other (https://somewhere)
*/
public function formatLinksInString(
$string,
$format = 'html',
$returnMatches = false
) {
$formatProtocol = $format == 'html'
? '<a href="$0" target="_blank" title="$0">$0</a>'
: ($format == 'short' || $returnMatches ? '[link:$0]' : '$0');
$formatSansProtocol = $format == 'html'
? '<a href="//$0" target="_blank" title="$0">$0</a>'
: ($format == 'short' || $returnMatches ? '[link://$0]' : '$0');
$formatMailto = $format == 'html'
? '<a href="mailto:$1" target="_blank" title="$1">$1</a>'
: ($format == 'short' || $returnMatches ? '[mailto:$1]' : '$1');
$regProtocol = '/(http|https|ftp|ftps)\:\/\/[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,}(\/[^\<\>\s]*)?/';
$regSansProtocol = '/(?<=\s|\A|\>)([0-9a-zA-Z\-\.]+\.[a-zA-Z0-9\/]{2,})(?=\s|$|\,|\<)/';
$regEmail = '/([^\s\>\<]+\@[^\s\>\<]+\.[^\s\>\<]+)\b/';
$consecutiveDotsRegex = $format == 'html'
? '/<a[^\>]+[\.]{2,}[^\>]*?>([^\<]*?)<\/a>/'
: '/\[link:.*?\/\/([^\]]+[\.]{2,}[^\]]*?)\]/';
// Protocol links
$formatString = preg_replace($regProtocol, $formatProtocol, $string);
// Sans Protocol Links
$formatString = preg_replace($regSansProtocol, $formatSansProtocol, $formatString); // use formatString from above
// Email - Mailto - Links
$formatString = preg_replace($regEmail, $formatMailto, $formatString); // use formatString from above
// Prevent consecutive periods from getting captured
$formatString = preg_replace($consecutiveDotsRegex, '$1', $formatString);
if ($returnMatches) {
// Find all [x:link] patterns
preg_match_all('/\[.*?:(.*?)\]/', $formatString, $matches);
current($matches); // to move pointer onto groups
return next($matches); // return the groups
}
return $formatString;
}
$string = 'example.com
www.example.com
http://example.com
https://example.com
http://www.example.com
https://www.example.com';
preg_match_all('#(\w*://|www\.)[a-z0-9]+(-+[a-z0-9]+)*(\.[a-z0-9]+(-+[a-z0-9]+)*)+(/([^\s()<>;]+\w)?/?)?#i', $string, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER);
foreach (array_reverse($matches) as $match) {
$a = '<a href="'.(strpos($match[1][0], '/') ? '' : 'http://') . $match[0][0].'">' . $match[0][0] . '</a>';
$string = substr_replace($string, $a, $match[0][1], strlen($match[0][0]));
}
echo $string;
结果:
example.com
<a href="http://www.example.com">www.example.com</a>
<a href="http://example.com">http://example.com</a>
<a href="https://example.com">https://example.com</a>
<a href="http://www.example.com">http://www.example.com</a>
<a href="https://www.example.com">https://www.example.com</a>
我在这个解决方案中喜欢的是它也转换www.example.com
为http://www.example.com
因为<a href="www.example.com"></a>
不起作用(没有http/https
它指向的协议yourdomain.com/www.example.com
)。
<?php
/**
* Turn all URLs in clickable links.
*
* @param string $value
* @param array $protocols http/https, ftp, mail, twitter
* @param array $attributes
* @return string
*/
public function linkify($value, $protocols = array('http', 'mail'), array $attributes = array())
{
// Link attributes
$attr = '';
foreach ($attributes as $key => $val) {
$attr .= ' ' . $key . '="' . htmlentities($val) . '"';
}
$links = array();
// Extract existing links and tags
$value = preg_replace_callback('~(<a .*?>.*?</a>|<.*?>)~i', function ($match) use (&$links) { return '<' . array_push($links, $match[1]) . '>'; }, $value);
// Extract text links for each protocol
foreach ((array)$protocols as $protocol) {
switch ($protocol) {
case 'http':
case 'https': $value = preg_replace_callback('~(?:(https?)://([^\s<]+)|(www\.[^\s<]+?\.[^\s<]+))(?<![\.,:])~i', function ($match) use ($protocol, &$links, $attr) { if ($match[1]) $protocol = $match[1]; $link = $match[2] ?: $match[3]; return '<' . array_push($links, "<a $attr href=\"$protocol://$link\">$link</a>") . '>'; }, $value); break;
case 'mail': $value = preg_replace_callback('~([^\s<]+?@[^\s<]+?\.[^\s<]+)(?<![\.,:])~', function ($match) use (&$links, $attr) { return '<' . array_push($links, "<a $attr href=\"mailto:{$match[1]}\">{$match[1]}</a>") . '>'; }, $value); break;
case 'twitter': $value = preg_replace_callback('~(?<!\w)[@#](\w++)~', function ($match) use (&$links, $attr) { return '<' . array_push($links, "<a $attr href=\"https://twitter.com/" . ($match[0][0] == '@' ? '' : 'search/%23') . $match[1] . "\">{$match[0]}</a>") . '>'; }, $value); break;
default: $value = preg_replace_callback('~' . preg_quote($protocol, '~') . '://([^\s<]+?)(?<![\.,:])~i', function ($match) use ($protocol, &$links, $attr) { return '<' . array_push($links, "<a $attr href=\"$protocol://{$match[1]}\">{$match[1]}</a>") . '>'; }, $value); break;
}
}
// Insert all link
return preg_replace_callback('/<(\d+)>/', function ($match) use (&$links) { return $links[$match[1] - 1]; }, $value);
}
不是我的代码,我是从这里得到的https://gist.github.com/jasny/2000705
如果是对的,您要做的就是将普通文本转换为 http 链接。以下是我认为可以提供帮助的内容:
<?php
$list = mysqli_query($con,"SELECT * FROM list WHERE name = 'table content'");
while($row2 = mysqli_fetch_array($list)) {
echo "<a target='_blank' href='http://www." . $row2['content']. "'>" . $row2['content']. "</a>";
}
?>