Reputation: 117
If I have a string and I want to split it at '.' which is not contained within brackets, how would I do it.
'(1.2).(2.1)'
to get ['(1.2)', '(2.1)']
'(1.2).2'
to get ['(1.2)', '2']
'1.(1.2)'
to get ['1', '(1.2)']
Upvotes: 6
Views: 895
Reputation: 239483
This program assumes that the input will be valid always, though it is fairly easy to include conditions to handle it properly.
def custom_split(data):
element, opened, result = "", 0, []
for char in data:
# Immediately following if..elif can be shortened like this
# opened += (char == ")") - (char == "(")
# Wrote like that for readability
if char == ")":
opened -= 1
elif char == "(":
opened += 1
if char == "." and opened == 0 and element != "":
result.append(element)
element = ""
else:
element += char
if element != "":
result.append(element)
return result
print custom_split('(1.2).(2.1)')
print custom_split('(1.2).2')
print custom_split('2.2')
print custom_split('(2.2)')
print custom_split('2')
Output
['(1.2)', '(2.1)']
['(1.2)', '2']
['2', '2']
['(2.2)']
['2']
Upvotes: 3
Reputation: 369134
def split(s, level=0, result=''):
if s == '':
if result:
return [result]
else:
return []
if s.startswith('.') and level == 0:
return [result] + split(s[1:], 0, '')
level += s.startswith('(')
level -= s.startswith(')')
return split(s[1:], level, result + s[0])
Usage:
>>> split('(1.2).(2.1)')
['(1.2)', '(2.1)']
>>> split('(1.2).2')
['(1.2)', '2']
>>> split('1.(1.2)')
['1', '(1.2)']
Upvotes: 0
Reputation: 123528
Using re
seems to be the solution:
>>> import re
>>> r = re.compile(r'(?:[^.(]|\([^)]*\))+')
>>> r.findall('(1.2).(2.1)')
['(1.2)', '(2.1)']
>>> r.findall('(1.2).2')
['(1.2)', '2']
>>> r.findall('1.(1.2)')
['1', '(1.2)']
Upvotes: 1
Reputation: 309929
This doesn't answer the general problem, but works for your examples:
>>> import re
>>> re.split(r'(?<=\))\.', '(1.2).(2.1)')
['(1.2)', '(2.1)']
>>> re.split(r'(?<=\))\.', '(1.2).2')
['(1.2)', '2']
This splits the string on any period after a closing parenthesis.
Upvotes: 3