需要帮助将包含空格的 bbcode URL 转换为有效的降价
Need help converting bbcode URLs that contain spaces to valid markdown
作为一些数据迁移的一部分,我正在将用户内容从 bbcode 转换为 markdown。
我正在自定义 MySQL 8.0.22 函数中进行转换,其中包含以下行以将 bbcode [url]
标签转换为 markdown:
...
SET markdown = REGEXP_REPLACE(markdown, '\[url=([^\]]+)\](.*?)\[\/url\]', '[]()', 1, 0, 'i');
...
这按预期执行,例如:
[url=https://whosebug.com/]SO[/url]
正确转换为 [SO](https://whosebug.com/)
问题是:某些 URL 包含空格,这不是有效的 markdown,因此无法在我的客户端正确显示。
是否可以修改我的 REGEXP_REPLACE
语句以将链接中的空格替换为“%20”?
如果可能,我想在 MySQL 中全部完成,但如果需要,可以在 C# 中对每条记录进行处理。
为了完整起见,我的整个 bbcode 到 markdown 函数是:
CREATE DEFINER=`root`@`localhost` FUNCTION `func_bb_to_md`(bbcode MEDIUMTEXT) RETURNS mediumtext CHARSET utf8mb4
DETERMINISTIC
BEGIN
DECLARE markdown MEDIUMTEXT;
SET markdown = bbcode;
SET markdown = REGEXP_REPLACE(markdown, '\[code\](.*?)\[\/code\]', '``', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[url\](.*?)\[\/url\]', '<>', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[url=([^\]]+)\](.*?)\[\/url\]', '[]()', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[img\](.*?)\[\/img\]', '![]()', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[yt\](.*?)\[\/yt\]', '![]()', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[b\](.*?)\[\/b\]', '****', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[i\](.*?)\[\/i\]', '**', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[u\](.*?)\[\/u\]', '', 1, 0, 'i');
SET markdown = REPLACE(markdown, '[list]', '');
SET markdown = REPLACE(markdown, '[list=1]', '');
SET markdown = REPLACE(markdown, '[/list]', '');
SET markdown = REPLACE(markdown, '[*]', '* ');
SET markdown = REGEXP_REPLACE(markdown, '\[color=([^\]]+)\](.*?)\[\/color\]', '', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[quote\](.*?)\[\/quote\]', '> ', 1, 0, 'i');
SET markdown = REPLACE(markdown, ':)', '{{slightly_smiling_face}}');
SET markdown = REPLACE(markdown, ';)', '{{wink}}');
SET markdown = REPLACE(markdown, ':D', '{{grin}}');
SET markdown = REPLACE(markdown, ':P', '{{stuck_out_tongue}}');
SET markdown = REPLACE(markdown, ':(', '{{frowning_face}}');
SET markdown = REPLACE(markdown, ':''(', '{{cry}}');
SET markdown = REPLACE(markdown, ':.', '{{flushed}}');
SET markdown = REPLACE(markdown, ':|', '{{neutral_face}}');
SET markdown = REPLACE(markdown, ':O', '{{open_mouth}}');
SET markdown = REPLACE(markdown, ':@', '{{angry}}');
SET markdown = REPLACE(markdown, ':S', '{{confused}}');
SET markdown = REPLACE(markdown, ':$', '{{blush}}');
SET markdown = REGEXP_REPLACE(markdown, '\{\{(.*?)\}\}', '::', 1, 0, 'i');
SET markdown = REPLACE(markdown, '\r\n', '\n');
SET markdown = REPLACE(markdown, '\n', '\r\n');
RETURN markdown;
END
在 C# 中,您可以将 Regex.Replace
与匹配计算器结合使用来操作捕获的文本。在MySQLREGEXP_REPLACE
中,您没有这个选项。
所以,您可以使用
var markdown = "[url=https://whosebug.com/a b]SO[/url]";
var p = @"(?i)\[url=([^]]+)](.*?)\[/url]";
var result = Regex.Replace(markdown, p, x =>
$"[{x.Groups[2].Value}]({x.Groups[1].Value.Replace(" ","%20")})");
Console.WriteLine(result);
(?i)\[url=([^]]+)](.*?)\[/url]
正则表达式匹配(以不区分大小写的方式)[url=
,将 ]
以外的任何一个或多个字符捕获到第 1 组,然后 [/url]
子字符串.匹配被传递给匹配评估器,x
是一个匹配对象。 $"[{x.Groups[2].Value}]({x.Groups[1].Value.Replace(" ","%20")})")
进行所有必要的操作。
作为一些数据迁移的一部分,我正在将用户内容从 bbcode 转换为 markdown。
我正在自定义 MySQL 8.0.22 函数中进行转换,其中包含以下行以将 bbcode [url]
标签转换为 markdown:
...
SET markdown = REGEXP_REPLACE(markdown, '\[url=([^\]]+)\](.*?)\[\/url\]', '[]()', 1, 0, 'i');
...
这按预期执行,例如:
[url=https://whosebug.com/]SO[/url]
正确转换为 [SO](https://whosebug.com/)
问题是:某些 URL 包含空格,这不是有效的 markdown,因此无法在我的客户端正确显示。
是否可以修改我的 REGEXP_REPLACE
语句以将链接中的空格替换为“%20”?
如果可能,我想在 MySQL 中全部完成,但如果需要,可以在 C# 中对每条记录进行处理。
为了完整起见,我的整个 bbcode 到 markdown 函数是:
CREATE DEFINER=`root`@`localhost` FUNCTION `func_bb_to_md`(bbcode MEDIUMTEXT) RETURNS mediumtext CHARSET utf8mb4
DETERMINISTIC
BEGIN
DECLARE markdown MEDIUMTEXT;
SET markdown = bbcode;
SET markdown = REGEXP_REPLACE(markdown, '\[code\](.*?)\[\/code\]', '``', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[url\](.*?)\[\/url\]', '<>', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[url=([^\]]+)\](.*?)\[\/url\]', '[]()', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[img\](.*?)\[\/img\]', '![]()', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[yt\](.*?)\[\/yt\]', '![]()', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[b\](.*?)\[\/b\]', '****', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[i\](.*?)\[\/i\]', '**', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[u\](.*?)\[\/u\]', '', 1, 0, 'i');
SET markdown = REPLACE(markdown, '[list]', '');
SET markdown = REPLACE(markdown, '[list=1]', '');
SET markdown = REPLACE(markdown, '[/list]', '');
SET markdown = REPLACE(markdown, '[*]', '* ');
SET markdown = REGEXP_REPLACE(markdown, '\[color=([^\]]+)\](.*?)\[\/color\]', '', 1, 0, 'i');
SET markdown = REGEXP_REPLACE(markdown, '\[quote\](.*?)\[\/quote\]', '> ', 1, 0, 'i');
SET markdown = REPLACE(markdown, ':)', '{{slightly_smiling_face}}');
SET markdown = REPLACE(markdown, ';)', '{{wink}}');
SET markdown = REPLACE(markdown, ':D', '{{grin}}');
SET markdown = REPLACE(markdown, ':P', '{{stuck_out_tongue}}');
SET markdown = REPLACE(markdown, ':(', '{{frowning_face}}');
SET markdown = REPLACE(markdown, ':''(', '{{cry}}');
SET markdown = REPLACE(markdown, ':.', '{{flushed}}');
SET markdown = REPLACE(markdown, ':|', '{{neutral_face}}');
SET markdown = REPLACE(markdown, ':O', '{{open_mouth}}');
SET markdown = REPLACE(markdown, ':@', '{{angry}}');
SET markdown = REPLACE(markdown, ':S', '{{confused}}');
SET markdown = REPLACE(markdown, ':$', '{{blush}}');
SET markdown = REGEXP_REPLACE(markdown, '\{\{(.*?)\}\}', '::', 1, 0, 'i');
SET markdown = REPLACE(markdown, '\r\n', '\n');
SET markdown = REPLACE(markdown, '\n', '\r\n');
RETURN markdown;
END
在 C# 中,您可以将 Regex.Replace
与匹配计算器结合使用来操作捕获的文本。在MySQLREGEXP_REPLACE
中,您没有这个选项。
所以,您可以使用
var markdown = "[url=https://whosebug.com/a b]SO[/url]";
var p = @"(?i)\[url=([^]]+)](.*?)\[/url]";
var result = Regex.Replace(markdown, p, x =>
$"[{x.Groups[2].Value}]({x.Groups[1].Value.Replace(" ","%20")})");
Console.WriteLine(result);
(?i)\[url=([^]]+)](.*?)\[/url]
正则表达式匹配(以不区分大小写的方式)[url=
,将 ]
以外的任何一个或多个字符捕获到第 1 组,然后 [/url]
子字符串.匹配被传递给匹配评估器,x
是一个匹配对象。 $"[{x.Groups[2].Value}]({x.Groups[1].Value.Replace(" ","%20")})")
进行所有必要的操作。