Para una expresión regular constante como en su ejemplo, hacer
re.sub("(this)(.*)(string)",
r'<markup>\1</markup>\2<markup>\3</markup>',
text)
en cuenta que necesita para encerrar. * Entre paréntesis, así si usted no quiere hacer perder.
Ahora, si no sabes cómo es la expresión regular, es más difícil, pero debería ser factible.
pattern = "(this)(.*)(string)"
re.sub(pattern,
lambda m: ''.join('<markup>%s</markup>' % s if n % 2 == 0
else s for n, s in enumerate(m.groups())),
text)
Si lo primero que acompañado de su patrón no necesariamente tiene que ser marcado, utilizar esto en su lugar, con el primer grupo que coincida con opcionalmente un texto de prefijo que se debe dejar solos:
pattern = "()(this)(.*)(string)"
re.sub(pattern,
lambda m: ''.join('<markup>%s</markup>' % s if n % 2 == 1
else s for n, s in enumerate(m.groups())),
text)
Ya entendiste la idea.
Si sus expresiones regulares son complicados y no está seguro de que puede hacer que todo parte de un grupo, en el que sólo cada segundo grupo tiene que ser marcado, es posible hacer algo más inteligente con una función más complicada:
pattern = "(this).*(string)"
def replacement(m):
s = m.group()
n_groups = len(m.groups())
# assume groups do not overlap and are listed left-to-right
for i in range(n_groups, 0, -1):
lo, hi = m.span(i)
s = s[:lo] + '<markup>' + s[lo:hi] + '</markup>' + s[hi:]
return s
re.sub(pattern, replacement, text)
Si necesita manejar grupos superpuestos, está solo, pero debería ser factible.
¿Qué representa el m en lamba m? – bikashg
La 'm' significa' match', el objeto de coincidencia [regexp] (https://docs.python.org/3/library/re.html#match-objects). –