Регулярное выражение для сопоставления значений между подстроками, где все средние значения являются одним и тем же символом.

Я пытаюсь стандартизировать набор текстовых файлов, содержащих список значений, разделенных каналами ("|"), которые в настоящее время имеют различные десятичные разряды для значений с конечными нулями.

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

В приведенном ниже коде Python показан минимальный пример того, чего я пытаюсь достичь (где должно пройти утверждение, если замена прошла успешно). Любая помощь приветствуется.

import re

str_in = '4|5|0.00000000|'
expected_str_out = '4|5|0.0|'

str_out = re.sub('0.(.*?)\|', '0.0|', s)
assert str_out == expected_str_out

Итак, какой regex вы используете сейчас? {regex} не может соответствовать ни одному числу. Вы хотите сказать, что 11111.111111 нужно заменить на 1.1? А если есть .5555?

Wiktor Stribiżew 17.05.2022 18:40
0.(.*?)\| — это один из протестированных мной примеров, который работает в этом примере, но также будет неправильно соответствовать, если str_in = '4|5|0.00other_characters00|'. Я поставил {regex}, чтобы указать, где я ввожу выражение. Я только ищу, где повторяющиеся символы равны 0
Ayrton Bourn 17.05.2022 18:45

Хорошо, я добавил это в вопрос, пожалуйста, добавьте еще несколько объяснений поведения и добавьте ожидаемое поведение (я думаю, тест должен быть верным)

Wiktor Stribiżew 17.05.2022 18:47
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения постов в Twitter с помощью Python, Tweepy и Flair
Анализ настроения текстовых сообщений может быть настолько сложным или простым, насколько вы его сделаете. Как и в любом ML-проекте, вы можете выбрать...
7 лайфхаков для начинающих Python-программистов
7 лайфхаков для начинающих Python-программистов
В этой статье мы расскажем о хитростях и советах по Python, которые должны быть известны разработчику Python.
Установка Apache Cassandra на Mac OS
Установка Apache Cassandra на Mac OS
Это краткое руководство по установке Apache Cassandra.
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
Сертификатная программа "Кванты Python": Бэктестер ансамблевых методов на основе ООП
В одном из недавних постов я рассказал о том, как я использую навыки количественных исследований, которые я совершенствую в рамках программы TPQ...
Создание персонального файлового хранилища
Создание персонального файлового хранилища
Вы когда-нибудь хотели поделиться с кем-то файлом, но он содержал конфиденциальную информацию? Многие думают, что электронная почта безопасна, но это...
Создание приборной панели для анализа данных на GCP - часть I
Создание приборной панели для анализа данных на GCP - часть I
Недавно я столкнулся с интересной бизнес-задачей - визуализацией сбоев в цепочке поставок лекарств, которую могут просматривать врачи и...
1
3
34
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ты можешь использовать

import re

str_in = '4|5|0.00000000|'
expected_str_out = '4|5|0.0|'

str_out = re.sub(r'(?<![^|])0+\.0+(?![^|])', '0.0', str_in)
print( str_out == expected_str_out )

См. онлайн-демонстрация Python и демонстрация регулярных выражений.

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

  • (?<![^|]) - начало строки или |
  • 0+\.0+ - один или несколько символов 0, . и один или несколько 0
  • (?![^|]) - конец строки или |.

Если вам нужно обрабатывать такие случаи, как 2.2222, 333.333, 5555555.55, вы можете использовать

(?<![^|])(\d)\1*\.\1+(?![^|])

Замените на \1.\1, см. демонстрация регулярных выражений.

Привет Виктор, спасибо за это. Как уже упоминалось в вопросе, я ищу совпадение только «когда значения между ними являются одним и тем же символом», к сожалению, с этим регулярным выражением оно также совпадает, если я говорю str_in = '4|5|0.00007000|'.

Ayrton Bourn 17.05.2022 19:11

@AyrtonBourn Что ты имеешь в виду? Мое решение не совпадает 4|5|0.00007000|.

Wiktor Stribiżew 17.05.2022 19:30

Ошибка с моей стороны, могу подтвердить, что теперь это работает. Большое тебе спасибо

Ayrton Bourn 17.05.2022 19:37

Последний вопрос, если можно, @wiktor-stribiżew. Как мне изменить это регулярное выражение, чтобы оно игнорировало число перед запятой? т.е. 1.0000 -> 1.0. Я пытался изменить отрицательный взгляд назад, но мне не повезло.

Ayrton Bourn 17.05.2022 20:04

@AyrtonBourn См. эта демонстрация регулярных выражений. re.sub(r'(?<![^|])(?:(0)+|(\d+))\.0+(?![^|])', r'\1\2.0', text)

Wiktor Stribiżew 17.05.2022 20:09

Другие вопросы по теме