I'm trying to append " Smith" to every name mapped to a spirit animal.
import re
contents = '''
var cool_spirit_animals = {
'Abel': 'unicorn',
'Bob': 'lion'
};
var spirit_plants = {
'Cain': 'venus fly trap'
};
var stupid_spirit_animals = {
'Dan': 'lamprey'
};
var spirit_vampires = {
'Emily': 'Buffy',
'Fred': 'Dracula'
};
'''
my_regex = r'(spirit_animals = \{[\n\r\s]*\'\w+)(\': [^\}]*)'
print re.sub(my_regex, r'\1 Smith\2', contents)
but my regex only changes the first name in every animals mapping. The script prints:
var cool_spirit_animals = {
'Abel Smith': 'unicorn',
'Bob': 'lion'
};
var spirit_plants = {
'Cain': 'venus fly trap'
};
var stupid_spirit_animals = {
'Dan Smith': 'lamprey'
};
var spirit_vampires = {
'Emily': 'Buffy',
'Fred': 'Dracula'
};
'Bob' didn't change - only 'Abel ' changed. How can I write a regex that appends Smith
to all names with spirit animals?
You can first match the spirit_animal
block and then add Smith
to the names inside a callback method to the re.sub
:
def repl(m):
return re.sub(r"'(\w+)':", r"'\1 Smith':", m.group())
my_regex = r'spirit_animals\s*=\s*\{[^}]*(?:}(?!;(?:$|\n))[^}]*)*};(?:$|\n)'
print re.sub(my_regex, repl, contents)
See the code demo
The spirit_animals\s*=\s*\{[^}]*(?:}(?!;(?:$|\n))[^}]*)*};(?:$|\n)
regex exatracts the spirit_animals
block (note it is an unrolled version of (?s)spirit_animals\s*=\s*\{.*?};(?:$|\n)
regex). The '(\w+)':
matches the names inside that block.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With