gpt4 book ai didi

regex - 使用python正则表达式转义无效的 Markdown

转载 作者:行者123 更新时间:2023-12-02 04:33:40 27 4
gpt4 key购买 nike

我一直在尝试编写一些 python 来转义“无效” Markdown 字符串。

这是用于需要使用\转义未使用的 Markdown 字符的 python 库 (python-telegram-bot)。

我的目标是匹配孤独 * , _ , `字符,以及无效的超链接 - 例如,如果没有提供链接,并转义它们。

我正在寻找的一个例子是:
*hello*很好,不应更改,而 hello*会变成hello\* .最重要的是,如果值是嵌套的,它们不应该被转义 - 例如 _hello*_应该保持不变。

我的想法是先匹配所有 double ,然后替换任何剩余的孤独字符。我使用 re.finditer() 管理了一个粗略的版本:

 def parser(txt):
match_md = r'(\*)(.+?)(\*)|(\_)(.+?)(\_)|(`)(.+?)(`)|(\[.+?\])(\(.+?\))|(?P<astx>\*)|(?P<bctck>`)|(?P<undes>_)|(?P<sqbrkt>\[)'
for e in re.finditer(match_md, txt):
if e.group('astx') or e.group('bctck') or e.group('undes') or e.group('sqbrkt'):
txt = txt[:e.start()] + '\\' + txt[e.start():]
return txt

note: regex was written to match *text*, _text_, `text`, [text](url), and then single *, _, `, [, knowing the last groups

但这里的问题当然是当您插入更多字符时偏移量会发生变化,因此一切都会发生变化。肯定有比添加偏移计数器更好的方法吗?

我尝试使用 re.sub(),但我一直无法找到如何替换特定组,或者我对 (?:) 有什么好运气“不匹配”有效的 Markdown 。

这是我的 re.sub 尝试:
def test(txt):
match_md = r'(?:(\*)(.+?)(\*))|' \
'(?:(\_)(.+?)(\_))|' \
'(?:(`)(.+?)(`))|' \
'(?:(\[.+?\])(\(.+?\)))|' \
'(\*)|' \
'(`)|' \
'(_)|' \
'(\[)'
return re.sub(match_md, "\\\\\g<0>", txt)

这只是在每个匹配项前面加上一个反斜杠(这是意料之中的,但我希望 ?: 会阻止它们被匹配。)

如果\已经在字符串中也被转义,那么它们就不会干扰当前的 Markdown - 这可能是错误的来源,因为图书馆会将其视为已转义,导致它看到其余部分为无效的。

提前致谢!

最佳答案

您可能正在寻找这样的正则表达式:

def test(txt):
match_md = r'((([_*]).+?\3[^_*]*)*)([_*])'
return re.sub(match_md, "\g<1>\\\\\g<4>", txt)

请注意,为清楚起见,我刚刚为 * 制作了一个样本。和 _ .您可以在 [] 中展开列表括号容易。现在让我们来看看这件事。

这个想法是处理看起来像 *foo_* 的字符串。或 _bar*_后跟不包含任何特殊内容的文本。匹配这样一个字符串的正则表达式是 ([_*]).+?\1[^_*]* : 我们匹配一个开始分隔符,将其保存在\1 中,然后沿着该行继续前进,直到我们看到相同的分隔符(现在正在关闭)。然后我们吃掉后面不包含任何分隔符的任何东西。

现在我们想要这样做,只要没有更多的分隔字符串,就可以用 (([_*]).+?\2[^_*]*)* 完成。 .现在右边剩下的,如果有的话,是一个孤立的特殊,这就是我们需要掩盖的。比赛结束后,我们有以下子比赛:
  • g<0> :整场比赛
  • g<1> : ((([_*]).+?\3[^_*]*)*) 的子匹配
  • g<2> : (([_*]).+?\3[^_*]*) 的子匹配
  • g<3> : ([_*]) 的子匹配(因此是上面的 \3)
  • g<4> : ([_*]) 的子匹配(屏蔽的)

  • 现在留给您的是找到如何处理无效超链接的方法,这是另一个主题。

    更新:
    不幸的是,这个解决方案掩盖了有效的 Markdown ,例如 *hello* (=> \*hello\*)。解决此问题的方法是在行尾添加一个特殊字符,并在替换完成后删除屏蔽的特殊字符。 OP 可能正在寻找更好的解决方案。

    关于regex - 使用python正则表达式转义无效的 Markdown ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46018581/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com