Уведомления

Группа в Telegram: @pythonsu

#1 Сен. 12, 2009 17:38:06

knkd
От:
Зарегистрирован: 2009-06-14
Сообщения: 225
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

У меня есть данные в фомате “Ключ = значение”, записаны в строку через пробелы, количество пролов между элементами зависит только от фазы луны.
Моя задача - получить в список все значения.

import re
raw = ' x=-125.789 y = .125E+5 z= 25. w = -.254E-5'
pat = '(?<==)\s*[+-E\d\.]+'
re.findall(pat, raw)
...
['-125.789', ' .125E+5', ' 25.', ' -.254E-5']
Проблема в том что значения получаются со всеми пробелами между знаком “=” и числом.
Можно конечно так:
import re
raw = ' x=-125.789 y = .125E+5 z= 25. w = -.254E-5'
pat = '(?<==)\s*[+-E\d\.]+'
[x.strip() for x in re.findall(pat, raw)]
...
['-125.789', '.125E+5', '25.', '-.254E-5']
Но хотелось бы сделать только регулярными выражениями :)
Такая вот попытка заканчивается неудачей:
import re
raw = ' x=-125.789 y = .125E+5 z= 25. w = -.254E-5'
pat = '(?<==\s*)[+-E\d\.]+'
re.findall(pat, raw)
...
error: look-behind requires fixed-width pattern
Получается что неизвестное количество пробелов включить в подобное условие нельзя?

А выделить в список сразу и ключи и значения без комбинации сплита и стрипа вообще не получается :(

Это всё возможно?



Офлайн

#2 Сен. 12, 2009 20:35:19

pasaranax
От:
Зарегистрирован: 2009-06-13
Сообщения: 574
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

pat = '(?<==)\s*([+-E\d\.]+)'
волшебные скобочки )



Офлайн

#3 Сен. 12, 2009 20:56:37

knkd
От:
Зарегистрирован: 2009-06-14
Сообщения: 225
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

pasaranax
pat = '(?<==)\s*([+-E\d\.]+)'
волшебные скобочки )
хм. Работает. А в чём дело?



Офлайн

#4 Сен. 12, 2009 22:08:12

pasaranax
От:
Зарегистрирован: 2009-06-13
Сообщения: 574
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

Скобки обособляют часть выражения. Вообще, у меня случайно получилось, я не думал, что re.findall будет выводить только обособленные скобками выражения. Если выделить несколько частей в скобки, то будет возвращен кортеж из этих выражений, таким образом можно выделить кроме значений еще и имена ключей.

pat = '\s*(\w*)\s*=\s*([+-E\d\.]+)'
если, конечно, \w* соответствует всем именам ключей



Офлайн

#5 Сен. 12, 2009 22:40:24

knkd
От:
Зарегистрирован: 2009-06-14
Сообщения: 225
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

pasaranax
Вообще, у меня случайно получилось, я не думал, что re.findall будет выводить только обособленные скобками выражения.
Вот ведь как бывет :)

В (Россуме|Откидаче) написано что выражение в скобках образует группу на которую можно ссылаться, но что выводится только та часть которая соответствует группам - такого нет. Новее книг нету… :(

В свете такого открытия получается что данная конструкция «(?<==)» в «(?<==)\s*(+)» полностью бессмысленна? Поскольку соответствует «=\s*(+)».

pat = '\s*(\w*)\s*=\s*([+-E\d\.]+)'
Ну тогда получается что «\s*» - совершенно лишняя, поскольку «\w» и так соответствует слову.
Теперь остаётся понять чем «\w» отличается от «\w*».

Тоесть, с превращением в словарь и приведением чисел в каноничный вид, получается:
raw    = """  x=-125.789  comment1  y    = .125E+5 z=  25. comment2  w = -.254E-5  d45 =123.e-2"""
regexp = "(\w*)\s*=\s*([+-eE\d\.]+)"

print dict((x[0], str(float(x[1]))) for x in re.findall(regexp, raw))
...
{'y': '12500.0', 'x': '-125.789', 'z': '25.0', 'd45': '1.23', 'w': '-2.54e-06'}
Вот, только со вчерашнего утра решился наконец взяться за регулярные выражения и уже сколько открытий :D



Отредактировано (Сен. 12, 2009 23:31:31)

Офлайн

#6 Сен. 12, 2009 23:44:01

pasaranax
От:
Зарегистрирован: 2009-06-13
Сообщения: 574
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

\w соответствует одному символу, а \w* соответствует 0-inf символам. И, пожалуй \w* стоит заменить на \w+, чтобы не получалось, что ключа может и не быть. А минус внутри квадратных скобок желательно тоже экранировать, потому что он там является спецсимволом, указывающим на диапазон (например, ), и будь он не справа от плюса, получилась бы ошибка.



Офлайн

#7 Сен. 13, 2009 00:04:48

knkd
От:
Зарегистрирован: 2009-06-14
Сообщения: 225
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

pasaranax
\w соответствует одному символу, а \w* соответствует 0-inf символам.
А я по описанию почему-то понял что \w соответствует всему слову :(

pasaranax
А минус внутри квадратных скобок желательно тоже экранировать, потому что он там является спецсимволом, указывающим на диапазон (например, ), и будь он не справа от плюса, получилась бы ошибка.
До такой ошибки я уже доэкстпериментировался :)

А вот ещё вопрос: Если данные необходимо разбить на секции по какому-нибудь признаку.
raw    = """section  x=-125.789   y    = .125E+5 z=  25.  section  w = -.254E-5  d45 =123.e-2"""
... "Должно получится"
[[('x', '-125.789'), ('y', '.125E+5')], [('w', '-.254E-5'), ('d45', '123.e-2')]]
Объединение в группу всего выражения «section\s*((\w+)\s*=\s*(+))*» даёт плохие результаты.



Отредактировано (Сен. 13, 2009 00:09:44)

Офлайн

#8 Сен. 13, 2009 01:00:55

pasaranax
От:
Зарегистрирован: 2009-06-13
Сообщения: 574
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

Это уже слишком сложно, тут нужно в 2 прохода - сначала секции выделить, а потом то, что выше делали, в каждой секции.



Офлайн

#9 Сен. 13, 2009 01:04:29

knkd
От:
Зарегистрирован: 2009-06-14
Сообщения: 225
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

pasaranax
тут нужно в 2 прохода
Эхх. А так хотелось :)



Офлайн

#10 Ноя. 17, 2009 21:17:20

straton
От:
Зарегистрирован: 2009-11-17
Сообщения: 4
Репутация: +  0  -
Профиль   Отправить e-mail  

Регулярные выражения

есть фрагмент кода:

temp = re.findall("[(.*),", text)
однако при попытке выполнения этого вылезает ошибка:
“unexpected end of regular expression” (переводить не надо, я и так знаю)
подскажите, в чем дело?



Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version