172
u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'

All I need is the contents inside the parenthesis.

nbro
  • 15,395
  • 32
  • 113
  • 196
user469652
  • 48,855
  • 59
  • 128
  • 165
  • 5
    Why not use double quotes? It would make the string easier to read, i.e. `u"abcde(date='2/xc2/xb2',time='/case/test.png')"` – kzh Feb 04 '11 at 03:01
  • 1
    This question makes me nervous just looking at it. I get the sneaking suspicion OP *really* wants the functionality in `ast` and just doesn't know it exists. – Kevin Feb 13 '15 at 02:10

11 Answers11

369

If your problem is really just this simple, you don't need regex:

s[s.find("(")+1:s.find(")")]
tkerwin
  • 9,559
  • 1
  • 31
  • 47
  • 18
    what if there is no '(' and ')'? you will get s[0:-1]. Which means you will get whatever in 's' :\. It will be good if you check that the string has parenthesis first. – Omar May 26 '16 at 01:21
  • 6
    What if you'll have "(some text (some text in inner parenthesis) some more text)"? – Ihor Pomaranskyy Jul 13 '16 at 12:17
  • 14
    Then the problem is not as simple as the original problem and will require a different solution. – tkerwin Jul 13 '16 at 17:26
  • 2
    For Igor's question: if you have nested parenthesis like that, you use rfind for the second part of the operation. See my post below for more details on this. – FaustoW Feb 17 '17 at 20:48
97

Use re.search(r'\((.*?)\)',s).group(1):

>>> import re
>>> s = u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'
>>> re.search(r'\((.*?)\)',s).group(1)
u"date='2/xc2/xb2',time='/case/test.png'"
user
  • 5,370
  • 8
  • 47
  • 75
waan
  • 1,121
  • 7
  • 9
81

If you want to find all occurences:

>>> re.findall('\(.*?\)',s)
[u"(date='2/xc2/xb2',time='/case/test.png')", u'(eee)']

>>> re.findall('\((.*?)\)',s)
[u"date='2/xc2/xb2',time='/case/test.png'", u'eee']
TheSoulkiller
  • 979
  • 8
  • 11
38

Building on tkerwin's answer, if you happen to have nested parentheses like in

st = "sum((a+b)/(c+d))"

his answer will not work if you need to take everything between the first opening parenthesis and the last closing parenthesis to get (a+b)/(c+d), because find searches from the left of the string, and would stop at the first closing parenthesis.

To fix that, you need to use rfind for the second part of the operation, so it would become

st[st.find("(")+1:st.rfind(")")]
FaustoW
  • 632
  • 7
  • 15
  • 2
    @ALH that expression does not have **nested** parenthesis, which is what my answer is good for. – FaustoW Dec 23 '19 at 20:51
10
import re

fancy = u'abcde(date=\'2/xc2/xb2\',time=\'/case/test.png\')'

print re.compile( "\((.*)\)" ).search( fancy ).group( 1 )
kzh
  • 19,810
  • 13
  • 73
  • 97
Anonymous
  • 101
  • 2
7
contents_re = re.match(r'[^\(]*\((?P<contents>[^\(]+)\)', data)
if contents_re:
    print(contents_re.groupdict()['contents'])
tread
  • 10,133
  • 17
  • 95
  • 170
  • 2
    While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value – sshashank124 Jan 22 '20 at 06:14
  • This worked like a charm including newline. Thanks for the solution. – Sunil Jun 09 '22 at 17:41
5

No need to use regex .... Just use list slicing ...

string="(tidtkdgkxkxlgxlhxl) ¥£%#_¥#_¥#_¥#"
print(string[string.find("(")+1:string.find(")")])
2

TheSoulkiller's answer is great. just in my case, I needed to handle extra parentheses and only extract the word inside the parentheses. a very small change would solve the problem

>>> s=u'abcde((((a+b))))-((a*b))'
>>> re.findall('\((.*?)\)',s)
['(((a+b', '(a*b']
>>> re.findall('\(+(.*?)\)',s)
['a+b', 'a*b']
fjahan
  • 113
  • 4
  • 10
1

Here are several ways to extract strings between parentheses in Pandas with the \(([^()]+)\) regex (see its online demo) that matches

  • \( - a ( char
  • ([^()]+) - then captures into Group 1 any one or more chars other than ( and )
  • \) - a ) char.

Extracting the first occurrence using Series.str.extract:

import pandas as pd
df = pd.DataFrame({'Description':['some text (value 1) and (value 2)']})
df['Values'] = df['Description'].str.extract(r'\(([^()]+)\)')
# => df['Values']
#    0    value 1
#    Name: Values, dtype: object

Extracting (finding) all occurrences using Series.str.findall:

import pandas as pd
df = pd.DataFrame({'Description':['some text (value 1) and (value 2)']})
df['Values'] = df['Description'].str.findall(r'\(([^()]+)\)')
# => df['Values']
#    0    [value 1, value 2]
#    Name: Values, dtype: object

df['Values'] = df['Description'].str.findall(r'\(([^()]+)\)').str.join(', ')
# => df['Values']
#    0    value 1, value 2
#    Name: Values, dtype: object

Note that .str.join(', ') is used to create a comma-separated string out of the resulting list of strings. You may adjust this separator for your scenario.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
0

If im not missing something, a small fix to @tkerwin: s[s.find("(")+1:s.rfind(")")]

The 2nd find should be rfind so you start search from end of string

-1

testcase

s = "(rein<unint>(pBuf) +fsizeof(LOG_RECH))"

result

['pBuf', 'LOG_RECH', 'rein<unint>(pBuf) +fsizeof(LOG_RECH)']

implement

def getParenthesesList(s):
    res = list()
    left = list()
    for i in range(len(s)):
        if s[i] == '(':
            left.append(i)
        if s[i] == ')':
            le = left.pop()
            res.append(s[le + 1:i])
    print(res)
    return res
Langewin
  • 1
  • 2