Son*_*ars 5 regex string markdown replace python-3.x
我一直在尝试编写一些 python 来转义“无效”降价字符串。
这是用于需要使用 \ 转义未使用的降价字符的 python 库 (python-telegram-bot)。
我的目标是匹配单独的*, _,`字符以及无效的超链接 - 例如,如果没有提供链接,并转义它们。
我正在寻找的一个例子是:
*hello*很好,不应该改变,而hello*会变成hello\*. 最重要的是,如果值是嵌套的,它们不应该被转义——例如_hello*_应该保持不变。
我的想法是先匹配所有双打,然后替换任何剩余的孤独字符。我使用 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
Run Code Online (Sandbox Code Playgroud)
但这里的问题当然是当您插入更多字符时偏移量会发生变化,因此一切都会发生变化。肯定有比添加偏移计数器更好的方法吗?
我尝试使用 re.sub(),但我无法找到如何替换特定组,或者有幸(?:)“不匹配”有效降价。
这是我的 re.sub 尝试:
def test(txt):
match_md = r'(?:(\*)(.+?)(\*))|' \
'(?:(\_)(.+?)(\_))|' \
'(?:(`)(.+?)(`))|' \
'(?:(\[.+?\])(\(.+?\)))|' \
'(\*)|' \
'(`)|' \
'(_)|' \
'(\[)'
return re.sub(match_md, "\\\\\g<0>", txt)
Run Code Online (Sandbox Code Playgroud)
这只是在每个匹配项前面加上一个反斜杠(这是意料之中的,但我希望 ?: 会阻止它们被匹配。)
如果 \ 已经在字符串中也被转义,那么它们就不会干扰当前的降价 - 这可能是错误的来源,因为图书馆会将其视为已转义,导致它将其余部分视为无效的。
提前致谢!
您可能正在寻找这样的正则表达式:
def test(txt):
match_md = r'((([_*]).+?\3[^_*]*)*)([_*])'
return re.sub(match_md, "\g<1>\\\\\g<4>", txt)
Run Code Online (Sandbox Code Playgroud)
*请注意,为了清楚起见,我只是为和制作了一个示例_。您可以轻松扩展括号中的列表[]。现在我们就来看看这个事情。
这个想法是处理看起来像*foo_*或_bar*_后面跟着不包含任何特殊字符的文本的字符串。匹配此类字符串的正则表达式是([_*]).+?\1[^_*]*:我们匹配一个开始分隔符,将其保存在 \1 中,然后沿着该行继续前进,直到看到相同的分隔符(现在结束)。然后我们吃掉后面不包含任何分隔符的任何东西。
现在,只要不再有分隔字符串,我们就希望这样做,这是通过(([_*]).+?\2[^_*]*)*. 现在右侧剩下的,如果有的话,是一个孤立的特殊情况,这就是我们需要掩盖的。比赛结束后,我们进行以下子比赛:
((([_*]).+?\3[^_*]*)*)(([_*]).+?\3[^_*]*)([_*])(因此\3上面)([_*])g<4> :(要屏蔽的)的子匹配现在剩下的就是找到一种方法来处理无效的超链接,这是另一个主题。
更新:
不幸的是,这个解决方案掩盖了有效的降价,例如*hello*(=> \*hello\*)。解决此问题的解决方法是在行尾添加一个特殊字符,并在替换完成后删除屏蔽的特殊字符。OP 可能正在寻找更好的解决方案。
| 归档时间: |
|
| 查看次数: |
1918 次 |
| 最近记录: |