Regex Match equal amount of two characters
<p>I'ld like to match the parameters of any function as a string using regex. As an example lets assume the following string:</p>

<pre><code>predicate(foo(x.bar, predicate(foo(...), bar)), bar)
</code></pre>

<p>this may be part of a longer sequence</p>

<pre><code>predicate(foo(x.bar, predicate(foo(...), bar)), bar)predicate(foo(x.bar, predicate(foo(...), bar)), bar)predicate(foo(x.bar, predicate(foo(...), bar)), bar)
</code></pre>

<p>I now want to find all substrings that represent a function/predicate and its parameters (i.e. in the first example the whole string as well as the nested <code>predicate(foo(...), bar)</code>). The problem is that I cant simply match like this</p>

<pre><code>predicate\(.*, bar\)
</code></pre>

<p>as i may then match more than the parameters of the predicate if the <code>*</code> is greedy, or less if it is lazy. Which is because such predicates() can be nested.</p>

<p>I need a regex that finds the string <code>predicate(...)</code> where <code>...</code> matches any string that contains an equal amount of <code>(</code>'s and <code>)</code>'s (lazy).</p>

<p>If it matters: I am using regex with the re module in python.</p>

<p>You can create a regex to find all of the function calls within your code. Something like this:</p>

<pre><code>([_a-zA-Z]+)(?=\()
</code></pre>

<p>Then using the <code>re</code> module, you create a data structure indexing the function calls within your code.</p>

<pre><code>import re

code = 'predicate(foo(x.bar, predicate(foo(...), bar)), bar)predicate(foo(x.bar, predicate(foo(...), bar)), bar)predicate(foo(x.bar, predicate(foo(...), bar)), bar)'
code_cp = code

regex = re.compile(r'([_a-zA-Z]+)(?=\()')
matches = re.findall(regex, code)
structured_matches = []

for m in matches:
    beg = str.index(code, m)
    end = beg + len(m)
    structured_matches.append((m, beg, end))
    code = code[:beg] + '_' * len(m) + code[end:]
</code></pre>

<p>This will give you a data structure that looks like this:</p>

<pre><code>[
  ('predicate', 0, 9),
  ('foo', 10, 13),
  ('predicate', 21, 30),
  ('foo', 31, 34),
  ('predicate', 52, 61),
  ('foo', 62, 65),
  ('predicate', 73, 82),
  ('foo', 83, 86),
  ('predicate', 104, 113),
  ('foo', 114, 117),
  ('predicate', 125, 134),
  ('foo', 135, 138)
]
</code></pre>

<p>You can use this data structure in conjunction with a <code>parse</code> function to pull out the contents of each function call's parens.</p>

<pre><code>def parse(string):
    stack = []
    contents = ''
    opened = False

    for c in string:
        if len(stack) &gt; 0:
            contents += c
        if c == '(':
            opened = True
            stack.append('o')
        elif c == ')':
            stack.pop()
            if opened and len(stack) == 0:
                break

    return contents[:-1]


paren_contents = []

for m in structured_matches:
    fn_name, beg, end = m
    paren_contents.append((fn_name, parse(code_cp[end:])))
</code></pre>

<p>In the end, <code>paren_contents</code> should look something like this:</p>

<pre><code>[
  ('predicate', 'foo(x.bar, predicate(foo(...), bar)), bar'),
  ('foo', 'x.bar, predicate(foo(...), bar)'),
  ('predicate', 'foo(...), bar'), ('foo', '...'),
  ('predicate', 'foo(x.bar, predicate(foo(...), bar)), bar'),
  ('foo', 'x.bar, predicate(foo(...), bar)'),
  ('predicate', 'foo(...), bar'), ('foo', '...'),
  ('predicate', 'foo(x.bar, predicate(foo(...), bar)), bar'),
  ('foo', 'x.bar, predicate(foo(...), bar)'),
  ('predicate', 'foo(...), bar'),
  ('foo', '...')
]
</code></pre>

<p>Hopefully this points you in the right direction.</p>

python regex first-order-logic