Форум сайта python.su
Привет всем.
В регулярках я не силён, всё что мог из себя на сегодня уже выжал, поэтому прошу помочь в решении проблемы.
Дана строка вида “(A,B,C),(D,E,F)”. Необходимо получить список строк “(A,B,C)”, “(D,E,F)”. Или без скобок, не принципиально. Сам я написал для этого что-то вроде этого:
re.compile(r"(\(.*?\)),{0,1}").findall(s)
>>> c = """(1,2,'3'),(1,2,'asd(asd)asd')"""
>>> re.compile(r"(\(.*?\)),{0,1}").findall(c)
["(1,2,'3')", "(1,2,'asd(asd)"]
Офлайн
import re
c = """(1,2,'3'),(1,2,'asd(asd)asd')"""
print re.split('(?<=\)),(?=\()', c)
["(1,2,'3')", "(1,2,'asd(asd)asd')"]
Офлайн
dimabest
Спасибо большое, твой вариант работает… пока не разобрался как, но работает :D. Но это уже сам в доках почитаю.
Офлайн
Да тут и без регулярок можно обойтись:
>>> c = """(1,2,'3'),(1,2,'asd(asd)asd')"""
>>> c = c.split("),(")
>>> c[0] = c[0][1:]
>>> c[-1] = c[-1][:-1]
>>> c
["1,2,'3'", "1,2,'asd(asd)asd'"]
Отредактировано (Март 24, 2010 19:49:18)
Офлайн
Rodegast, спасибо за ответ.
Кстати оба примера могут засыпаться на таком:
>>> c = """(1,2,'3),(')"""
>>> c.split("),(")
["(1,2,'3", "')"]
>>> re.compile(r"(\(.*?\)),{0,1}").findall(c)
["(1,2,'3)", "(')"]
Отредактировано (Март 24, 2010 21:34:56)
Офлайн
Вы просто не внимательно смотрели код : ) После разбития строки на список в первом и последнем элементе остаются остатки от скобок. Они и удаляются следующими двумя строками.
Офлайн
Rodegast
Не, я просто невнимательно привёл результат, извиняюсь)). Проблема не в “лишних” скобках, а в количестве подстрок, которое мы получим (2, а должна быть одна). Так наглядней будет:
>>> c = """(1,2,'3),(')"""
>>> c.split("),(")
["(1,2,'3", "')"]
>>> [_[0][1:], _[-1][:-1]]
["1,2,'3", "'"] # а хотелось бы получить ["1,2,'3),('"]
Офлайн
Попробую описать всё ещё раз и полностью :). Необходимо выдернуть из строки все N (N >= 1) блоков значений. Блоки значений заключены в скобки и разделены запятыми. Содержание блоков - значения через запятую. Значения могут быть цифрами или строками. Строковые значения заключены в одинарные кавычки. Одинарные и двойные кавычки в строковых значениях экранируются. Одиночные слэши экранируются. Как-то так…
Вот мой велосипед, если кому интересно, но хотелось сделать красивей, поэтому начал с регулярок :)
def process_values(values):
not_quoted = True
not_escaped = True
prev_position = 0
for i in xrange(len(values)):
if values[i] == ')' and not_quoted:
yield values[prev_position:i+1]
prev_position = i
elif values[i] == "'" and not_escaped:
not_quoted ^= True
elif values[i] == '(' and not_quoted:
prev_position = i
elif values[i] == '\\':
not_escaped ^= True
elif values[i] == "'" or values[i] == '"' \
or values[i] == 'r' or values[i] == 'n' \
and not not_escaped:
not_escaped = True
c = r"""(1,2,'\'3\\'),(1,2,'),('),(1,2,'\"3\\')"""
for val in process_values(c):
print val
(1,2,'\'3\\')
(1,2,'),(')
(1,2,'\"3\\')
Отредактировано (Март 25, 2010 00:02:24)
Офлайн
Первое что пришло в голову:
# py31
print(list(str(x) for x in eval(a)))
Отредактировано (Март 26, 2010 10:12:47)
Офлайн
Griffon, гениально :D
Офлайн