Вот общий метод, который я использовал в прошлом для таких случаев:
Используйте функцию sub
модуля re
с функцией в качестве аргумента замены. Функция отслеживает открытие и закрытие парсеров, кронштейнов и брекетов, а также одиночные и двойные кавычки и выполняет замену только за пределами таких заключенных в скобки и подкатегорий. Затем вы можете заменить запятые без кавычек на другой символ, который, как вы уверены, не отображается в строке (я использую код ASCII / Unicode group-separator: chr (29)), а затем простую строку. раскол на этот символ. Вот код:
import re
def srchrepl(srch, repl, string):
"""Replace non-bracketed/quoted occurrences of srch with repl in string"""
resrchrepl = re.compile(r"""(?P<lbrkt>[([{])|(?P<quote>['"])|(?P<sep>["""
+ srch + """])|(?P<rbrkt>[)\]}])""")
return resrchrepl.sub(_subfact(repl), string)
def _subfact(repl):
"""Replacement function factory for regex sub method in srchrepl."""
level = 0
qtflags = 0
def subf(mo):
nonlocal level, qtflags
sepfound = mo.group('sep')
if sepfound:
if level == 0 and qtflags == 0:
return repl
else:
return mo.group(0)
elif mo.group('lbrkt'):
level += 1
return mo.group(0)
elif mo.group('quote') == "'":
qtflags ^= 1 # toggle bit 1
return "'"
elif mo.group('quote') == '"':
qtflags ^= 2 # toggle bit 2
return '"'
elif mo.group('rbrkt'):
level -= 1
return mo.group(0)
return subf
Если у вас нет nonlocal
в вашей версии Python, просто измените его на global
и определите level
и qtflags
на уровне модуля.
Вот как он используется:
>>> GRPSEP = chr(29)
>>> string = "Wilbur Smith (Billy, son of John), Eddie Murphy (John), Elvis Presley, Jane Doe (Jane Doe)"
>>> lst = srchrepl(',', GRPSEP, string).split(GRPSEP)
>>> lst
['Wilbur Smith (Billy, son of John)', ' Eddie Murphy (John)', ' Elvis Presley', ' Jane Doe (Jane Doe)']