Reputation: 5533
I'm using re.sub
to replace ARB-style names with GLSL-style ones in a string. Now I want to additionally store all converted matches into a set of strings. Can I do this while still using the "template" syntax of re.sub
?
Here is the code:
# set of replacement rules
expl_table = [
(r'program.env\[(\d+)\]' , r'program_env_\1'),
(r'program.local\[(\d+)\]', r'program_local_\1'),
]
for props in expl_table:
(re_from, re_to) = props
# arg = re.sub(re_from, re_to, arg) # simple and good
def replace_func(m):
result = ??repl_template??(m, re_to) # where can I find it?
declarations.append(result) # want to save all replacements
return result
arg = re.sub(re_from, replace_func, arg)
I have found something like _subx
in source code, but it seems to be closed.
It seems that I have to implement it myself, as stupid as it sounds.
Upvotes: 3
Views: 141
Reputation: 43169
You could change your string while iterating over it with re.finditer()
:
# set of replacement rules
expl_table = [
(r'program.env\[(\d+)\]' , r'program_env_dsdsds\1'),
(r'program.local\[(\d+)\]', r'program_local_\1'),
]
declarations = []
for props in expl_table:
(re_from, re_to) = props
offset = 0
for m in re.finditer(re_from, string):
sub = m.expand(re_to)
string = string[:m.start()+offset] + sub + string[m.end()+offset:]
offset = max(map(len, [sub, m.group(0)])) - min(map(len, [sub, m.group(0)]))
declarations.append(sub)
print(string)
Alternatively, you could "upgrade" a lambda function within the same scope. Usually, it's not allowed to use multiple statements within a lambda function but a list comprehension somewhat bypasses that constraint:
for props in expl_table:
(re_from, re_to) = props
string = re.sub(re_from,
lambda m: [
(result, declarations.append(result))
for result in [m.expand(re_to)]
][0][0],
string)
print(string)
print(declarations)
Upvotes: 1