Python: Number BackReference em re.sub
-
05-07-2019 - |
Pergunta
Estou tentando usar a função Re.sub do Python para substituir algum texto.
>>> import re
>>> text = "<hi type=\"italic\"> the></hi>"
>>> pat_error = re.compile(">(\s*\w*)*>")
>>> pat_error.search(text)
<_sre.SRE_Match object at 0xb7a3fea0>
>>> re.sub(pat_error, ">\1", text)
'<hi type="italic">\x01</hi>'
Depois, o valor do texto deve ser
"<hi type="italic"> the</hi>"
Solução
Dois bugs em seu código. Primeiro, você não está combinando (e especificamente, captura) o que você acha que está combinando e capturando - insira após sua chamada para .search
:
>>> _.groups()
('',)
A repetição irrestrita de repetições (estrela após um grupo de captura com nada além de estrelas) combina uma vez muitas - com a corda vazia no final do que você pensa que está combinando - e é isso que é capturado. Corrija alterando pelo menos uma das estrelas para uma vantagem, por exemplo, por:
>>> pat_error = re.compile(r">(\s*\w+)*>")
>>> pat_error.search(text)
<_sre.SRE_Match object at 0x83ba0>
>>> _.groups()
(' the',)
Agora isso corresponde e captura de maneira sensata. Segundo, você não está usando a sintaxe literal de cordas cruas onde você deve, para não ter uma barra de barragem onde pensa que tem uma - você tem uma sequência de fuga \1
que é o mesmo que Chr (1). Corrija usando a sintaxe literal de cordas cruas, ou seja, depois do trecho acima
>>> pat_error.sub(r">\1", text)
'<hi type="italic"> the</hi>'
Como alternativa, você pode dobrar todas as suas barris, para evitar que sejam tomadas como o início das sequências de fuga - mas a sintaxe literal de cordas cruas é muito mais legível.
Outras dicas
>>> text.replace("><", "<")
'<hi type="italic"> the</hi>'