tags:

views:

288

answers:

2

How can I match one or more parenthetical expressions appearing at the end of string?

Input:

'hello (i) (m:foo)'

Desired output:

['i', 'm:foo']

Intended for a python script. Paren marks cannot appear inside of each other (no nesting), and the parenthetical expressions may be separated by whitespace.

It's harder than it might seem at first glance, at least so it seems to me.

+5  A: 

You don't need to use regex:

def splitter(input):
    return [ s.rstrip(" \t)") for s in input.split("(") ][1:]
print splitter('hello (i) (m:foo)')

Note: this solution only works if your input is already known to be valid. See MizardX's solution that will work on any input.

too much php
The spec is that we only match parenthetical expressions at the end of the string. The given implementation doesn't work if we have parenthetical expressions which *aren't* at the end of the string which we want to avoid matching.
Charles Duffy
certainly clever. you could do `for s in input.split("(") if s` rather than the [1:]
ʞɔıu
+6  A: 
paren_pattern = re.compile(r"\(([^()]*)\)(?=(?:\s*\([^()]*\))*\s*$)")

def getParens(s):
  return paren_pattern.findall(s)

or even shorter:

getParens = re.compile(r"\(([^()]*)\)(?=(?:\s*\([^()]*\))*\s*$)").findall

explaination:

\(                     # opening paren
([^()]*)               # content, captured into group 1
\)                     # closing paren
(?=                    # look ahead for...
  (?:\s*\([^()]*\))*   #   a series of parens, separated by whitespace
  \s*                  #   possibly more whitespace after
  $                    #   end of string
)                      # end of look ahead
MizardX