如何使用 bbcode 标签的值将 bbcode url 标签转换为 html 超链接?
How to convert bbcode url tag to an html hyperlink using the bbcode tag's values?
如何将 bbcode [url]
标签转换为具有 href 属性和开始和结束标签之间文本的 <a>
标签?
以下是一些示例字符串:
[url]https://any.com/any[/url]
[URL="https://any.com/any?any=333"]text text[/URL]
[url]http://www.any.com/any?any=44#sss[/url]
*请注意,开头 [url]
标记中的双引号子字符串是可选的,它会影响所需的输出...
我试过这个模式:
(?:\[url="(https?://(?:www)?.+?)\]|\[url\](https?://(?:www)?.+\[))
\[url="(https?:\/\/(?:www\.)?.+?)\]|\[url\](https?:\/\/(?:www\.)?.+)\[\/url\]
\[url="(https?:\/\/(?:www\.)?.+)"\]|\[url\](https?:\/\/(?:www\.)?.+)\[\/url\]
类似的东西:
$pattern ='##i';
$text = preg_replace($pattern,'',$text);
我想要的上述 bbcode url 标签的结果应该是:
<a href="https://any.com/any">https://any.com/any</a>
<a href="https://any.com/any?any=333">text text</a>
<a href="http://www.any.com/any?any=44#sss">http://www.any.com/any?any=44#sss</a>
换句话说,如果 url 位于开头 [url]
标记的双引号部分,则使用该值作为 href
值并保留[url]
标记作为生成的 <a>
标记的 innerHTML。
如果 url 不在双引号部分而是位于开始和结束 [url]
标记之间,则使用该值作为 href
值和 innerHTML <a>
.
你可以使用
(?i)\[url(?|="(?P<url>[^"]+)|\](?P<url>[^][]+))
细分:
(?i) # case insensitive
\[url # [url
(?| # branch reset
="(?P<url>[^"]+) # either ="..."
| # or
\](?P<url>[^][]+) # ]...[/url]
)
无论哪种情况,您都需要组 "url"。
UPDATE: Casimir's commented solution is more direct/clean.
代码:(Demo) (Pattern Demo)
echo preg_replace('~\[url(?|]((https?://[^[]+))|(?:="(https?://[^"]+)")](.+?))\[/url]~i', '<a href=\"\"></a>', $bbcode);
通过将模式中第一个替代项的捕获加倍,您可以确保始终有 </code> 和 <code>
应用于替换字符串。
这里a slightly extended variation of the pattern考虑了单引号和不引号。
(上一个解决方案的开始)
通过使用 preg_match_callback()
,您可以确定是否在 [url]
开始标记内提供了 url -- 在这种情况下,您将希望保留位于开始和结束标签之间。
如果标签之间的文本是 url,您可以在 <a>
标签字符串的两个地方使用它。
无效的字符串将不会被转换。
代码:(Demo) (Pattern Demo)
$bbcodes = [
'[URL]www.no.http.example.com[/URL]',
'[url]https://any.com/any[/url]',
'[url="nourl"]nourl[/url]',
'[URL="https://any.com/any?any=333"]text text[/URL]',
'[url="http://www.emptyTEXT.com"][/url]',
'[url]http://www.any.com/any?any=44#sss[/url]',
'[url="https://conflictinglink"]http://differenturl[/url]'
];
foreach ($bbcodes as $bbcode) {
echo preg_replace_callback('~\[url(?:](https?://[^[]+)|(?:="(https?://[^"]+)")](.+?))\[/url]~i',
function($m) {
if (isset($m[2])) {
return "<a href=\"{$m[2]}\">{$m[3]}</a>";
}
return "<a href=\"{$m[1]}\">{$m[1]}</a>";
},
$bbcode);
echo "\n---\n";
}
输出:
[URL]www.no.http.example.com[/URL]
---
<a href="https://any.com/any">https://any.com/any</a>
---
[url="nourl"]nourl[/url]
---
<a href="https://any.com/any?any=333">text text</a>
---
[url="http://www.emptyTEXT.com"][/url]
---
<a href="http://www.any.com/any?any=44#sss">http://www.any.com/any?any=44#sss</a>
---
<a href="https://conflictinglink">http://differenturl</a>
---
模式分解:
~ #start of pattern delimiter
\[url #match literally [url
(?: #start non-capturing group #1
] #match literally ]
(https?://[^[]+) #match and store as Capture Group #1 http , an optional s , colon , two forward slashes, then one or more non-opening square brackets (since valid href values cannot have square brackets)
| #or
(?: #start non-capturing group #2
=" #match literally ="
(https?://[^"]+) #match and store as Capture Group #2 (same logic as Capture Group #1)
" #match literally "
) #end non-capturing group #2
] #match literally ]
(.+?) #match (lazily) and store as Capture Group #3 one or more characters (this is the innerHTML component)
) #end non-capturing group #1
\[/url] #match literally [/url]
~ #end of pattern delimiter
回调函数评估 匹配 数组 ($m
) 中的元素并有条件地生成和 returns 所需的输出。如果有任何匹配项,输出将包含:
array(
0 => [the fullstring match]
1 => [the url of a bbcode tag that does not have a quoted url]
)
或
array(
0 => [the fullstring match]
1 => '' // <-- empty string
2 => [the quoted url of the bbcode tag]
3 => [the text between the opening an closing bbcode tags]
)
如何将 bbcode [url]
标签转换为具有 href 属性和开始和结束标签之间文本的 <a>
标签?
以下是一些示例字符串:
[url]https://any.com/any[/url]
[URL="https://any.com/any?any=333"]text text[/URL]
[url]http://www.any.com/any?any=44#sss[/url]
*请注意,开头 [url]
标记中的双引号子字符串是可选的,它会影响所需的输出...
我试过这个模式:
(?:\[url="(https?://(?:www)?.+?)\]|\[url\](https?://(?:www)?.+\[))
\[url="(https?:\/\/(?:www\.)?.+?)\]|\[url\](https?:\/\/(?:www\.)?.+)\[\/url\]
\[url="(https?:\/\/(?:www\.)?.+)"\]|\[url\](https?:\/\/(?:www\.)?.+)\[\/url\]
类似的东西:
$pattern ='##i';
$text = preg_replace($pattern,'',$text);
我想要的上述 bbcode url 标签的结果应该是:
<a href="https://any.com/any">https://any.com/any</a>
<a href="https://any.com/any?any=333">text text</a>
<a href="http://www.any.com/any?any=44#sss">http://www.any.com/any?any=44#sss</a>
换句话说,如果 url 位于开头 [url]
标记的双引号部分,则使用该值作为 href
值并保留[url]
标记作为生成的 <a>
标记的 innerHTML。
如果 url 不在双引号部分而是位于开始和结束 [url]
标记之间,则使用该值作为 href
值和 innerHTML <a>
.
你可以使用
(?i)\[url(?|="(?P<url>[^"]+)|\](?P<url>[^][]+))
细分:
(?i) # case insensitive
\[url # [url
(?| # branch reset
="(?P<url>[^"]+) # either ="..."
| # or
\](?P<url>[^][]+) # ]...[/url]
)
无论哪种情况,您都需要组 "url"。
UPDATE: Casimir's commented solution is more direct/clean.
代码:(Demo) (Pattern Demo)
echo preg_replace('~\[url(?|]((https?://[^[]+))|(?:="(https?://[^"]+)")](.+?))\[/url]~i', '<a href=\"\"></a>', $bbcode);
通过将模式中第一个替代项的捕获加倍,您可以确保始终有 </code> 和 <code>
应用于替换字符串。
这里a slightly extended variation of the pattern考虑了单引号和不引号。
(上一个解决方案的开始)
通过使用 preg_match_callback()
,您可以确定是否在 [url]
开始标记内提供了 url -- 在这种情况下,您将希望保留位于开始和结束标签之间。
如果标签之间的文本是 url,您可以在 <a>
标签字符串的两个地方使用它。
无效的字符串将不会被转换。
代码:(Demo) (Pattern Demo)
$bbcodes = [
'[URL]www.no.http.example.com[/URL]',
'[url]https://any.com/any[/url]',
'[url="nourl"]nourl[/url]',
'[URL="https://any.com/any?any=333"]text text[/URL]',
'[url="http://www.emptyTEXT.com"][/url]',
'[url]http://www.any.com/any?any=44#sss[/url]',
'[url="https://conflictinglink"]http://differenturl[/url]'
];
foreach ($bbcodes as $bbcode) {
echo preg_replace_callback('~\[url(?:](https?://[^[]+)|(?:="(https?://[^"]+)")](.+?))\[/url]~i',
function($m) {
if (isset($m[2])) {
return "<a href=\"{$m[2]}\">{$m[3]}</a>";
}
return "<a href=\"{$m[1]}\">{$m[1]}</a>";
},
$bbcode);
echo "\n---\n";
}
输出:
[URL]www.no.http.example.com[/URL]
---
<a href="https://any.com/any">https://any.com/any</a>
---
[url="nourl"]nourl[/url]
---
<a href="https://any.com/any?any=333">text text</a>
---
[url="http://www.emptyTEXT.com"][/url]
---
<a href="http://www.any.com/any?any=44#sss">http://www.any.com/any?any=44#sss</a>
---
<a href="https://conflictinglink">http://differenturl</a>
---
模式分解:
~ #start of pattern delimiter
\[url #match literally [url
(?: #start non-capturing group #1
] #match literally ]
(https?://[^[]+) #match and store as Capture Group #1 http , an optional s , colon , two forward slashes, then one or more non-opening square brackets (since valid href values cannot have square brackets)
| #or
(?: #start non-capturing group #2
=" #match literally ="
(https?://[^"]+) #match and store as Capture Group #2 (same logic as Capture Group #1)
" #match literally "
) #end non-capturing group #2
] #match literally ]
(.+?) #match (lazily) and store as Capture Group #3 one or more characters (this is the innerHTML component)
) #end non-capturing group #1
\[/url] #match literally [/url]
~ #end of pattern delimiter
回调函数评估 匹配 数组 ($m
) 中的元素并有条件地生成和 returns 所需的输出。如果有任何匹配项,输出将包含:
array(
0 => [the fullstring match]
1 => [the url of a bbcode tag that does not have a quoted url]
)
或
array(
0 => [the fullstring match]
1 => '' // <-- empty string
2 => [the quoted url of the bbcode tag]
3 => [the text between the opening an closing bbcode tags]
)