title: How to loop over regex matches and do replacement, without using a separate replacement function?
body: <p>I need to replace every pattern like: <code>{foo}</code> by <code>FOO</code> + an increasing number, and also <code>do_something_else(...)</code> for each match. Example :</p>
  
  <p><code>'hell{o} this {is} a t{est}'</code> => <code>hellO1 this IS2 a tEST3</code></p>
  
  <p>How to do it <strong>without using a replacement function</strong>, but just with <strong>a loop over matches</strong>? I'm looking for something like:</p>
  
  <pre><code>import re
  
  def do_something_else(x, y):  # dummy function
      return None, None
  
  def main(s):
      i = 0
      a, b = 0, 0
      for m in re.findall(r"{([^{}]+)}", s):  # loop over matches, can we
          i += 1                              # do the replacement DIRECTLY IN THIS LOOP?
          new = m.upper() + str(i)
          print(new)
          s = s.replace('{' + m + '}', new)    # BAD here because: 1) s.replace is not ok! bug if "m" is here mutliple times   
                                               #                   2) modifying s while looping on f(.., s) is probably not good
          a, b = do_something_else(a, b)
      return s
  
  main('hell{o} this {is} a t{est}')    # hellO1 this IS2 a tEST3
  </code></pre>
  
  <hr>
  
  <p>The following code (<em>with</em> a replacement function) works but the use of global variables is a big problem here here because in fact <code>do_something_else()</code> can take a few milliseconds, and this process might be mixed with another concurrent run of <code>main()</code> :</p>
  
  <pre><code>import re
  
  def replace(m):
      global i, a, b
      a, b = do_something_else(a, b)
      i += 1
      return m.group(1).upper() + str(i)
  
  def main(s):
      global i, a, b
      i = 0
      a, b = 0, 0
      return re.sub(r"{([^{}]+)}", replace, s)
  
  main('hell{o} this {is} a t{est}')
  </code></pre>