import io
import tokenize as T
from operator import itemgetter
def tokenize_string(data):
tokens = T.tokenize(io.BytesIO(data.strip().encode()).readline)
next(tokens) # skip encoding token
return list(filter(None, map(itemgetter(1), tokens))) # filter ENDMARKER
text = 'a, b, c, d, "e, f, g"'
tokens = [x for x in tokenize_string(text) if x != ',']
print(tokens)
# ['a', 'b', 'c', 'd', '"e, f, g"']
UPD。
强制从字符串中删除引号:
tokens = [x[1:-1] if x.startswith('"') and x.endswith('"') else x for x in tokenize_string(text) if x != ',']
print(tokens)
# ['a', 'b', 'c', 'd', 'e, f, g']
import re
t = 'a, b, c, d, "e, g, h", k'
# находим с помощью регулярных выражений составные элементы
x = re.findall('"[^\"]*"', t)
# объявляем словарик
d = dict()
# пробегаемся по списку наших составных элементов ['"e, g, h"']
# в n - у нас индекс элемента, в xx - сам элемент
for n, xx in enumerate(x):
# придумываем псевдоним для составного элемента на основе индекса
q = '@{}'.format(n)
# добавляем в словарь выходное значение составного элемента
d[q] = xx.replace('"', '')
# заменяем составной элемент на псевдоним
t = t.replace(xx, q)
# здесь 2 цикла, в первом текст t, который стал выглядеть вот так:
# 'a, b, c, d, @0, k' подвергаем split(','), а затем к каждому элементу
# применяем strip (s.strip())
# во втором цикле пробегаемся по всем элементам и если элемент (g) является
# ключом словаря (g in d) то заменяем его значением из словаря
tt = [d[g] if g in d else g for g in [s.strip() for s in t.split(',')]]
# ['a', 'b', 'c', 'd', 'e, g, h', 'k']
def _recursive_filter(line, result=None):
try:
if not result:
result = []
line = line.strip()
if line.startswith('"'):
temp = ''
i = 0
while line[i+1] != '"':
temp += line[i]
i += 1
else:
temp += f'{line[i]}"'
result.append(temp)
line = line[len(temp):].strip(', ')
_recursive_filter(line, result)
else:
temp = ''
i = 0
while line[i] != ',':
temp += line[i]
i += 1
else:
temp += ','
result.append(temp)
line = line[len(temp):]
_recursive_filter(line, result)
return [x.strip(', "') for x in result]
except IndexError:
if temp:
result.append(temp)
if __name__ == "__main__":
print(_recursive_filter('"d, e, f", g, h,'))
您可以尝试通过tokenize处理字符串。
例子:
UPD。
强制从字符串中删除引号:
我可以建议这种“笨拙”的方法
您可以用单个元素替换组成元素(以导致一般情况),然后执行必要的操作 -
split,然后将组成部分从字典中返回到它的位置我的决定。适用于任意数量的双引号元素和任意数量的双引号元素。