¿Cómo escribo una expresión regular para reemplazar una palabra pero mantengo su caso en Python?

¿Esto es posible?

Basically, I want to turn these two calls to sub into a single call:

re.sub(r'\bAword\b', 'Bword', mystring)
re.sub(r'\baword\b', 'bword', mystring)

What I'd really like is some sort of conditional substitution notation like:

re.sub(r'\b([Aa])word\b', '(?1=A:B,a:b)word')

I only care about the capitalization of the first character. None of the others.

preguntado el 30 de junio de 12 a las 17:06

If you use a replacement function you can perform "advanced stuff" for the replacement value. See re.sub where is says "repl can be a string or a function". -

ou have to describe what form your target words take. Is it always a contiguous string where only the case of the first character is to be changed, for example? -

Ok, looking into replacement functions, although I feel like that is cheating when it comes to regular expressions :( -

Its not cheating. You want conditional replacements. The regex is doing its job to match and capture your pattern. But what you want is to examine the reault first before deciding its replacement. -

I know regular expressions are cool and all, but if your usage is really this simplistic, i would avoid them... for regular expressions, "with great power, comes great obscurity"... -

4 Respuestas

You can have functions to parse every match:

>>> def f(match):
        return chr(ord(match.group(0)[0]) + 1) + match.group(0)[1:]

>>> re.sub(r'\b[aA]word\b', f, 'aword Aword')
'bword Bword'

Respondido el 30 de junio de 12 a las 17:06

@ConleyOwens I did that way because it can work with different expressions in the form [xX]any_word :) - bernardo

This is a cute answer, but it only works for substituting 'a' -> 'b' and 'A' -> 'B' - tel

@tel Because that was what was specified in the original question. If you were smart you could adapt this answer to work on any letter you like instead of down voting it. You just have to change the matching regex where it says [aA] a algo más como \w - bernardo

OK, here's the solution I came up with, thanks to the suggestions to use a replace function.

re.sub(r'\b[Aa]word\b', lambda x: ('B' if x.group()[0].isupper() else 'b') + 'word', 'Aword  aword.')

Respondido el 30 de junio de 12 a las 17:06

You can pass a lambda function which uses the Match object as a parameter as the replacement function:

import re
re.sub(r'\baword\b', 
       lambda m: m.group(0)[0].lower() == m.group(0)[0] and 'bword' or 'Bword',
       'Aword aword', 
       flags=re.I)
# returns: 'Bword bword'

Respondido el 30 de junio de 12 a las 17:06

a and b or c is horribly outdated -- use b if a else c. - Katriel

Use capture groups (r'\1'):

 re.sub(r'\b([Aa])word\b', r'\1word', "hello Aword")

Respondido 24 Abr '20, 22:04

I wanted to substitute with a different letter. i.e., I want the result to be "Bword", not "Aword". - Conley Owens

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.