referencia de grupo no válida cuando se usa re.sub()

Tengo problemas con re.sub. Entiendo por otras respuestas que esto se debe al hecho de que me estoy refiriendo a un grupo de captura que no tengo.

Mi pregunta es: ¿cómo ajusto mi código para tener un grupo válido?

s = "hello a world today b is sunny c day"
markers = "a b c".split()
pattern = r'\b' + ' (?:\w+ )?(?:\w+ )?'.join(markers) + r'\b'
text = re.sub(pattern, r'<b>\1</b>', s)   # this gives error

Quiero tener esto: "hello <b>a world today b is sunny c</b> day"

Answer

No puede usar \1la referencia inversa de reemplazo si no hay grupos de captura en el patrón. Agregue el grupo de captura al patrón:

pattern = r'\b(' + ' (?:\w+ )?(?:\w+ )?'.join(markers) + r')\b' # or
              ^                                            ^
pattern = r'\b({})\b'.format(r' (?:\w+ )?(?:\w+ )?'.join(markers))

O simplemente use \g<0>para insertar la coincidencia completa en lugar de un valor de grupo de captura (entonces, no es necesario modificar su expresión regular):

text = re.sub(pattern, r'<b>\g<0></b>', s) 

Vea la demostración de Python .

No tienes ningún grupo en tu expresión regular.

(?:...) es un grupo sin captura, supongo que quieres

pattern = r'\b(' + ' (?:\w+ )?(?:\w+ )?'.join(markers) + r')\b'

Este código puede obtener el resultado que desea. Lo he probado.

import re
s = "hello a world today b is sunny c day"
pat = r'(a.*c)'
result = re.sub(pat,r'<b>\1</b>',s)