Уведомления

Группа в Telegram: @pythonsu

#1 Март 24, 2010 00:14:29

lizzard
От:
Зарегистрирован: 2009-03-05
Сообщения: 48
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

Привет всем.

В регулярках я не силён, всё что мог из себя на сегодня уже выжал, поэтому прошу помочь в решении проблемы.

Дана строка вида “(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)"]
А хотелось бы получить список . Никак не соображу что подправить надо, подскажите плиз %).



Офлайн

#2 Март 24, 2010 04:17:27

dimabest
От:
Зарегистрирован: 2009-02-12
Сообщения: 253
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

import re

c = """(1,2,'3'),(1,2,'asd(asd)asd')"""

print re.split('(?<=\)),(?=\()', c)
результат:
["(1,2,'3')", "(1,2,'asd(asd)asd')"]
Твоя регулярка не работает по той простой причине, что в строке есть вложенные скобки.



Офлайн

#3 Март 24, 2010 09:33:31

lizzard
От:
Зарегистрирован: 2009-03-05
Сообщения: 48
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

dimabest
Спасибо большое, твой вариант работает… пока не разобрался как, но работает :D. Но это уже сам в доках почитаю.



Офлайн

#4 Март 24, 2010 19:48:24

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2742
Репутация: +  183  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

Да тут и без регулярок можно обойтись:

>>> 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)

Офлайн

#5 Март 24, 2010 21:34:31

lizzard
От:
Зарегистрирован: 2009-03-05
Сообщения: 48
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

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)

Офлайн

#6 Март 24, 2010 21:45:08

Rodegast
От: Пятигорск
Зарегистрирован: 2007-12-28
Сообщения: 2742
Репутация: +  183  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

Вы просто не внимательно смотрели код : ) После разбития строки на список в первом и последнем элементе остаются остатки от скобок. Они и удаляются следующими двумя строками.



С дураками и сектантами не спорю, истину не ищу.
Ели кому-то правда не нравится, то заранее извиняюсь.

Офлайн

#7 Март 24, 2010 21:52:28

lizzard
От:
Зарегистрирован: 2009-03-05
Сообщения: 48
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

Rodegast
Не, я просто невнимательно привёл результат, извиняюсь)). Проблема не в “лишних” скобках, а в количестве подстрок, которое мы получим (2, а должна быть одна). Так наглядней будет:

>>> c = """(1,2,'3),(')"""
>>> c.split("),(")
["(1,2,'3", "')"]
>>> [_[0][1:], _[-1][:-1]]
["1,2,'3", "'"] # а хотелось бы получить ["1,2,'3),('"]



Офлайн

#8 Март 24, 2010 23:10:50

lizzard
От:
Зарегистрирован: 2009-03-05
Сообщения: 48
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

Попробую описать всё ещё раз и полностью :). Необходимо выдернуть из строки все 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)

Офлайн

#9 Март 26, 2010 10:08:45

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

Первое что пришло в голову:

# py31
print(list(str(x) for x in eval(a)))
upd: где А - наша строка.



Отредактировано (Март 26, 2010 10:12:47)

Офлайн

#10 Март 27, 2010 10:22:31

lizzard
От:
Зарегистрирован: 2009-03-05
Сообщения: 48
Репутация: +  0  -
Профиль   Отправить e-mail  

Помогите допилить регулярное выражение

Griffon, гениально :D



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version