0

Tehre doesn't appear to be a clear answer on how to do this the best way.

I have some bbcode which may have links in bbcode format:

[url=http://thisisalink.com]link[/url]

as well as possible copy/pasted urls:

http://thisisalink.com

I want to replace both instances with a clickable link. I currently have the following: regexs running:

"/\[link=http:\/\/(.*?)\](.*?)\[\/link\]/is"
"/\[link=https:\/\/(.*?)\](.*?)\[\/link\]/is"
"/\[link=(.*?)\](.*?)\[\/link\]/is"

$URLRegex = '/(?:(?<!(\[\/link\]|\[\/link=))(\s|^))'; // No [url]-tag in front and is start of string, or has whitespace in front
$URLRegex.= '(';                                    // Start capturing URL
$URLRegex.= '(https?|ftps?|ircs?):\/\/';            // Protocol
$URLRegex.= '\S+';                                  // Any non-space character
$URLRegex.= ')';                                    // Stop capturing URL
$URLRegex.= '(?:(?<![[:punct:]])(\s|\.?$))/i';      // Doesn't end with punctuation and is end of string, or has whitespace after

It just seems that I can't get both to work. In this case, the last regex seems to unlink the first regex.

Surely this has been documented somewhere on the best way to get both bbcode links and pasted URLs to link up together without conflicting with each other.

4

2 回答 2

2

您可以做的是使用以 bbcode 模式开头的替代,以避免替换 bbcode 标记内的链接,例如:

$pattern = '~\[url\s*+=\s*+([^]\s]++)]([^[]++)\[/url]|((http://\S++))~i';
$result = preg_replace($pattern, '<a href="$1$3">$2$4</a>', $string);

请注意,我已经捕获了两次复制/粘贴的 url,以避免使用preg_replace_callback函数。

我为复制/粘贴的 url 使用了简化模式,但是您可以将其替换为您想要处理的https、ftp、ftps ...。

于 2013-06-17T16:32:30.243 回答
0

我最终选择了这个。然后我通过它做一个回调,它允许我在 php 中做一些特殊的代码来检查一些链接:

# MATCH '?://www.link.com' and make it a bbcode link
$URLRegex = '/(?:(?<!(\[\/link\]|\[\/link=))(\s|^))'; // No [url]-tag in front and is start of string, or has whitespace in front
$URLRegex.= '(';                                    // Start capturing URL
$URLRegex.= '(https?|ftps?|ircs?|http?|ftp?|irc?):\/\/';            // Protocol
$URLRegex.= '\S+';                                  // Any non-space character
$URLRegex.= ')';                                    // Stop capturing URL
$URLRegex.= '(?:(?<![[:punct:]])(\s|\.?$))/i';
$output = preg_replace($URLRegex, "$2[link=$3]$3[/link]$5", $output);

# MATCH 'www.link.com' and make it a bbcode link
$URLRegex2 = '/(?:(?<!(\[\/link\]|\[\/link=))(\s|^))'; // No [url]-tag in front and is start of string, or has whitespace in front
$URLRegex2.= '(';                                    // Start capturing URL
$URLRegex2.= 'www.';            // Protocol
$URLRegex2.= '\S+';                                  // Any non-space character
$URLRegex2.= ')';                                    // Stop capturing URL
$URLRegex2.= '(?:(?<![[:punct:]])(\s|\.?$))/i';
$output = preg_replace($URLRegex2, "$2[link=http://$3]$3[/link]$5", $output);


# link up a [link=....]some words[/link]
$output = preg_replace_callback(
    "/\[link=(.*?):\/\/(.*?)\](.*?)\[\/link\]/is", 
    Array($this,'bbcode_format_link1'),
    $output);
于 2013-06-18T11:48:59.317 回答