Форум русскоязычного сообщества Ubuntu


За новостями русскоязычного сообщества и Ubuntu в целом можно следить на нашей страничке в Google+

Автор Тема: Python, помогите составить рег. выражение  (Прочитано 706 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6748
  • Ubuntu 16.04
    • Просмотр профиля
(3090, 234.2904),(12, 0.0),(491, 13.3952382038e-5)Нужно убрать из строки все, что не подходит под заданный выше формат. Что-то под вечер совсем не идет...

Вот заготовочка, чтобы сразу можно было проверить:
#!/usr/bin/env python3

import re

s = "(32, +inf),(3090, 234.2904),(12, 0.0),(491, 13.3952382038e-5),(33, -inf)"
s2 = re.sub( r'\(\d+, \d+\.\d+(e[\+,-]{1}\d+)?\),?' , '' , s )
print(s)
print(s2)

Тут я удаляю только нужное, как инвертировать выражение?
« Последнее редактирование: 14 Апрель 2016, 16:18:11 от thunderamur »

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6748
  • Ubuntu 16.04
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #1 : 14 Апрель 2016, 16:19:32 »
s2 = re.sub( r'[^\(\d+, \d+\.\d+(e[\+,-]{1}\d+)?\),?]*' , '' , s )Вроде с помощью [^ ] инверсия делается, но получаю ошибку при выполнении.
(Нажмите, чтобы показать/скрыть)

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #2 : 15 Апрель 2016, 00:02:28 »
thunderamur, если использовать findall — как раз получишь в списке что надо
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6748
  • Ubuntu 16.04
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #3 : 15 Апрель 2016, 08:50:59 »
Azure,
Да я пробовал findall - получил не то, что хотел

#!/usr/bin/env python3

import re

s = "(32, +inf),(3090, 234.2904),(12, 0.0),(491, 13.3952382038e-5),(33, -inf)"
s2 = re.sub( r'\(\d+, \d+\.\d+(e[\+,-]{1}\d+)?\),?' , '' , s )
s3 = re.findall( r'\(\d+, \d+\.\d+(e[\+,-]{1}\d+)?\),?' , s )
print(s)
print(s2)
print(s3)

(32, +inf),(3090, 234.2904),(12, 0.0),(491, 13.3952382038e-5),(33, -inf)
(32, +inf),(33, -inf)
['', '', 'e-5']

Пользователь добавил сообщение 15 Апрель 2016, 09:07:42:
re.findall( '(\(\d+, \d+\.\d+e?[\+,-]?\d*\),?)' , s )['(3090, 234.2904),', '(12, 0.0),', '(491, 13.3952382038e-5),']
Вот так получаю, что надо, но эта часть вообще не красивая:
e?[\+,-]?\d*Можно как-то описать, что это один блок и он может быть, а может не быть, типа
(e[\+,-]\d+)?Просто в таком случае findall выбирает отдельно это выражение и получается
[('(3090, 234.2904),', ''), ('(12, 0.0),', ''), ('(491, 13.3952382038e-5),', 'e-5')]

Пользователь добавил сообщение 15 Апрель 2016, 09:09:27:
И все-таки хотелось бы решить через sub, чтобы потом не тратить процессорное время на ещё одну команду - сбор строки из массива.
« Последнее редактирование: 15 Апрель 2016, 09:09:27 от thunderamur »

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #4 : 15 Апрель 2016, 16:30:25 »
Код: Python
  1. re.findall('(?:\([0-9,. e+-]+\),?)+', s)
Код: Python
  1. re.findall('\((?:[()0-9,. e+-]+)+\)', s)
А зачем "собирать"? Сразу обращайся к элементу списка.
И вообще для правильной регулярки надо попробовать словами выразить, что именно ты хочешь получить.
« Последнее редактирование: 15 Апрель 2016, 16:36:00 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6748
  • Ubuntu 16.04
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #5 : 16 Апрель 2016, 04:58:24 »
Azure, собирать нужно, т.к. я из этого добра готовлю мега-sql-запрос в 75 кБ.

Твой вариант приятнее, использую его, спасибо.

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #6 : 16 Апрель 2016, 10:39:07 »
thunderamur, насчет «собирать» ты меня не понял. Твоя регулярка дает список из 3 элементов, моя — из 1-го. Во вторых, «мега-запрос» гораздо быстрее объединить одним join чем каждый раз складывать по строкам…
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6748
  • Ubuntu 16.04
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #7 : 16 Апрель 2016, 13:10:31 »
Azure,
1. Ухты я не заметил сразу, но заметил бы позже, когда применил бы это дело, на работе скрипт пишу этот.
2. Таки join и использую, ибо скорость выполнения для той задачи важна, поэтому в поисках ускорения я его использовал уже ранее.
3. Я сейчас проверил оба варианта подробнее и пришел в выводу, что мой вариант более строгий, мне он больше подходит для валидации данных.

s2 = re.findall( '(\(\d+, \d+\.\d+e?[\+,-]?\d*\))' , s )
s3 = re.findall('\((?:[()0-9,. e+-]+)+\)', s)

(32, +inf),(3090, 234.2904),(-12, 0.0),(491, e),(33, -inf)
['(3090, 234.2904)']
['(3090, 234.2904),(-12, 0.0),(491, e)']

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #8 : 17 Апрель 2016, 10:25:28 »
Исходный код можно заменить на любой какой угодно более строгий, если знать какие именно данные надо исключать (нужен пример возможных вариантов). Поэтому лучше всего
словами выразить, что именно ты хочешь получить.
Код: Python
  1. re.findall('(?:\([0-9,. e+-]+\d\),?){3}', s)[0]
« Последнее редактирование: 17 Апрель 2016, 10:29:38 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн thunderamur

  • Автор темы
  • Заслуженный пользователь
  • Старожил
  • *
  • Сообщений: 6748
  • Ubuntu 16.04
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #9 : 17 Апрель 2016, 12:09:17 »
Azure, я хочу получить следующее в указанном порядке:
(
integer unsigned
,
space
float
)

Все что не подходит не по символам не по порядку следования - не брать.

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 5661
  • elementaryOS 0.4 Loki, i3wm on Debian9
    • Просмотр профиля
Re: Python, помогите составить рег. выражение
« Ответ #10 : 18 Апрель 2016, 11:57:11 »
Если всё именно так строго, то можно использовать и твой вариант(только скобки лишние убрать). Кроме того для ускорения имеет смысл предварительно скомпилировать регулярку.
Код: Python
  1. pattern = re.compile(r'\(\d+, \d*\.\d+[eE]?[+-]?\d+\)')
  2. s3 = re.findall(pattern, s)
« Последнее редактирование: 18 Апрель 2016, 11:58:49 от Azure »
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

 

Страница сгенерирована за 0.065 секунд. Запросов: 24.