Парсинг текста в квадратных и обычных скобках
Задача вывести текст из, допустим такой строки - "[текст1] (текст2)". Проблема усложняется тем, что таких строк много написанных через азбац. Ниже пример того, что я хочу спарсить и какой результат получить на выходе.
['строка1'] ('текст1')
['строка2'] ('текст2')
['строка3'] ('текст3')
Где на выходе хочу получить многомерный список вида
parsed = ['строка1', 'текст1'], ['строка2', 'текст2'], ['строка3','текст3']
Ответы (4 шт):
Можно где то так
#!/usr/bin/python3
import re
# здесь спрятана вся магия. Не пытайтесь это прочитать, можно что то вызывать
regex = r"(\['([^]]+)'\]|\('([^)]+)'\))"
r = []
f = open("data.txt")
# читаем файл построчно
for l in f:
# тут будет улов с текущей строки
sb = []
matches = re.findall(regex, l)
# если ничего не нашли - то и делать нечего
if len(matches) == 0:
continue
# по всем найденным кусочкам смотрим
for x in matches:
# у нас там два варианта, поэтому проверяем, где зарылся бегемот
if (x[1] == ''):
sb.append(x[2])
else:
sb.append(x[1])
# и добавляем найденный массив в больший
r.append(sb)
# осталось по мелочам - распечатать это все дело.
print(r)
Если же строки файла содержат только указанные в примере варианты (там по две строки), то все можно сильно-сильно упростить
#!/usr/bin/python3
import re
regex = r"(\['([^]]+)'\]\s*\('([^)]+)'\))"
r = []
f = open("data.txt")
for l in f:
matches = re.findall(regex, l)
if len(matches) == 0 or len(matches[0]) != 3:
continue
r.append([matches[0][1], matches[0][2]])
print(r)
Некоторые люди могут предлагать использовать "питоник-вей", но он хорош для "однократных задач".
у KoVadim какой-то сложный ответ выше вышел. Как мне кажется, можно немного проще спарсить.
import re
text = """['строка1'] ('текст1')
['строка2'] ('текст2')
['строка3'] ('текст3')"""
parsed = list(map(list, re.findall("\['(\w+)'\]\s+\('(\w+)'\)", text)))
import re
txt = """['строка1'] ('текст1')
['строка2'] ('текст2')
['строка3'] ('текст3')"""
data = re.findall(r"(?<=[\[(]').+?(?='[)\]])", txt, flags=re.S)
print(
*map(list, zip(data[::2], data[1::2]))
)
# ['строка1', 'текст1'] ['строка2', 'текст2'] ['строка3', 'текст3']
print(
list(map(list, zip(data[::2], data[1::2])))
)
# [['строка1', 'текст1'], ['строка2', 'текст2'], ['строка3', 'текст3']]
print(
dict(zip(data[::2], data[1::2]))
)
# {'строка1': 'текст1', 'строка2': 'текст2', 'строка3': 'текст3'}
Лёгкий способ
s = '''\
['строка1'] ('текст1')
['строка2'] ('текст2')
['строка3'] ('текст3')
'''
l = [[eval(i.split()[0])[0], eval(i.split()[1])] for i in s.split('\n') if i]
print(l)
# [['строка1', 'текст1'], ['строка2', 'текст2'], ['строка3', 'текст3']]