2

I googled and read up on some codes here Regular expression to return text between parenthesis

but say for example I have the following string

"[Guide] Strength (STR) is recommended on Warriors (Warriors -> Berserker)"

How would I output "STR" only and not (Warriors -> Berserker) ?

Thanks!

xvienxz2
  • 53
  • 1
  • 5
  • I think you actually mean the word in the first pair of parentheses, not the first word in parentheses; otherwise it would include `Warriors` as well. – blhsing Oct 26 '18 at 05:59

6 Answers6

1
>>> import re
>>> s = "[Guide] Strength (STR) is recommended on Warriors (Warriors -> Berserker)"
>>> re.search(r'\(([^)]+)\)', s).group(1)
<<< 'STR'

re.search returns the first match
.group(1) returns the contents of the first capture group, which is ([^)]+)

KingRadical
  • 1,282
  • 11
  • 8
1

Consider the following string,

s = 'I am John (John (M) Doe)'

The first word within valid parentheses should be 'John (M) Doe' and not 'John (M'. The following code would keep count of the open and closed parentheses:

opn = 0
close = 0
new_str = ''
add = False
for i in s:
    if not add:
        if i == '(':
            opn += 1
            add = True
    else:
        if i == '(':
            new_str += i
            opn += 1
        elif i == ')':
            close += 1
            if opn == close:
                break
            else:
                new_str += i
        else:
            new_str += I

print(new_str)

This yields:

John (M) Doe

Hope this helps!

Mahen Gandhi
  • 351
  • 2
  • 8
0

Or re.split:

>>> import re
>>> s="[Guide] Strength (STR) is recommended on Warriors (Warriors -> Berserker)"
>>> result = re.split(r"\s+(?=[^()]*(?:\(|$))", s)
>>> next((i[1:-1] for i in result if i[0]=='(' and i[-1]==')'),'No sub-strings that are surrounded by parenthesis')
'STR'
>>> 

Note: here if the strings does not contain any sub-string surrounded by parenthesis, it will Output 'No sub-strings that are surrounded by parenthesis', if that's not needed you can just do:

>>> next((i[1:-1] for i in result if i[0]=='(' and i[-1]==')'))

Or:

>>> [i[1:-1] for i in result if i[0]=='(' and i[-1]==')'][0]
U13-Forward
  • 69,221
  • 14
  • 89
  • 114
0
import re
str1 = "[Guide] Strength (STR) is recommended on Warriors (Warriors -> Berserker)"
m = re.findall(r'(\(\w+\))',str1)
print m

Result:['(STR)']

Here the string we need to find in given text is located between ( ) with no spaces and special charecters,So ( \w+ ) means more than one charecters present in ( )

Harsha Biyani
  • 7,049
  • 9
  • 37
  • 61
Narendra Lucky
  • 340
  • 2
  • 13
  • Hi, above comment was the part from "Review" in stack over flow. I am not looking for your answer. I was just reviewing the quality of code. It is good practice to add some explanation. You can edit your answer and and can add the comments. – Harsha Biyani Oct 26 '18 at 08:20
  • 1
    @Harsha B thanks for the suggestion,next time this reminds me :) – Narendra Lucky Oct 26 '18 at 09:27
0

Use re.search with group as explained by @KingRadical or use re.findall and then select the first element.

s = "[Guide] Strength (STR  are long) is recommended on Warriors (Warriors -> Berserker)"
re.findall('\(([^\)]+)\)', s) # returns all matches

>>> ['STR  are long', 'Warriors -> Berserker']

re.findall('\(([^\)]+)\)', s)[0] # returns the first match which is what you want.

>>> 'STR  are long'

Note:

If there is no match in the string s, re.findall will return an empty list while re.search will return a None object.

Samuel Nde
  • 2,565
  • 2
  • 23
  • 23
0

You can slice the string with indices returned by str.find:

s = "[Guide] Strength (STR) is recommended on Warriors (Warriors -> Berserker)"
s[s.find('(')+1:s.find(')')]

which returns: STR

blhsing
  • 91,368
  • 6
  • 71
  • 106