需要帮助将包含空格的bbcode URL转换为有效markdown

安德鲁祖库

作为某些数据迁移的一部分,我正在将用户内容从bbcode转换为markdown。

我正在使用自定义MySQL 8.0.22函数进行转换,该函数包含以下[url]代码,可将bbcode标签转换为markdown:

...
SET markdown = REGEXP_REPLACE(markdown, '\\[url=([^\\]]+)\\](.*?)\\[\\/url\\]', '[$2]($1)', 1, 0, 'i');
...

这将按预期执行,例如:

[url=https://stackoverflow.com/]SO[/url] 完全转换为 [SO](https://stackoverflow.com/)

问题是:某些URL包含空格,这不是有效的降价促销,并且不能在我的客户端正确显示。

是否可以修改我的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`', 1, 0, 'i'); 
    SET markdown = REGEXP_REPLACE(markdown, '\\[url\\](.*?)\\[\\/url\\]', '<$1>', 1, 0, 'i'); 
    SET markdown = REGEXP_REPLACE(markdown, '\\[url=([^\\]]+)\\](.*?)\\[\\/url\\]', '[$2]($1)', 1, 0, 'i'); 
    
    SET markdown = REGEXP_REPLACE(markdown, '\\[img\\](.*?)\\[\\/img\\]', '![]($1)', 1, 0, 'i'); 
    
    SET markdown = REGEXP_REPLACE(markdown, '\\[yt\\](.*?)\\[\\/yt\\]', '![]($1)', 1, 0, 'i'); 
    
    SET markdown = REGEXP_REPLACE(markdown, '\\[b\\](.*?)\\[\\/b\\]', '**$1**', 1, 0, 'i'); 
    SET markdown = REGEXP_REPLACE(markdown, '\\[i\\](.*?)\\[\\/i\\]', '*$1*', 1, 0, 'i'); 
    SET markdown = REGEXP_REPLACE(markdown, '\\[u\\](.*?)\\[\\/u\\]', '$1', 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\\]', '$2', 1, 0, 'i'); 
    SET markdown = REGEXP_REPLACE(markdown, '\\[quote\\](.*?)\\[\\/quote\\]', '> $1', 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:', 1, 0, 'i');
    
    SET markdown = REPLACE(markdown, '\r\n', '\n');
    SET markdown = REPLACE(markdown, '\n', '\r\n');

    RETURN markdown;
END
维克多·史翠比维

在C#中,您可以使用Regex.Replace匹配评估器来处理捕获的文本。在MySQL中REGEXP_REPLACE,您没有此选项。

因此,您可以使用

var markdown = "[url=https://stackoverflow.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);

在线观看此C#演示

(?i)\[url=([^]]+)](.*?)\[/url]正则表达式匹配(在不区分大小写的方式)[url=,捕获任何一个或多个字符比其他]成第1组,然后[/url]子串。匹配项传递给匹配评估器,它x是一个匹配对象。$"[{x.Groups[2].Value}]({x.Groups[1].Value.Replace(" ","%20")})")进行所有必要的操作。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章