Python Regex для включения/извлечения только чисел, десятичных знаков и дефиса (-)

Я не очень хорошо разбираюсь в регулярных выражениях и пытаюсь, но не могу извлечь только numbers, decimals and - из столбца в Python.

Еще лучше, если пробелы также можно удалить, но даже если и нет, то с этим все равно можно справиться.

Я проверил ^(\d.+)|[-], ^(\d.+)|[-]?[^a-z]+$/i и ^(\d.+)|[-]?(\d+)?, но ни один из них не работал правильно.

Тестовые случаи (в основном это диапазоны из несовместимого формата)

28193.13
28913
28913-13
28193.13-28193.13
28193.13 - 28193.13
28193.13 - 28193.13 / cm
 - 28193.13
 -28193.13
 28913-
 28913 -

Кадр данных

test_df = pd.DataFrame({"Range": [28193.13,28913,'28913-13','28193.13-28193.13',
'28193.13 - 28193.13','28193.13 - 28193.13 / cm', '- 28193.13','28913-','28913 -']})

test_df

Код пробовал: test_df['Range'].str.extract(r"^(\d.+)|[-]?[^a-z]+$/i")

Желаемые результаты в вышеуказанных случаях:

28193.13
28913
28913-13
28193.13-28193.13
28193.13-28193.13
28193.13-28193.13
-28193.13
-28193.13
28913-
28913-

Проблема: я не могу удалить символы из этого 28193.13 - 28193.13 / cm с помощью моего кода регулярного выражения, поскольку желаемым результатом будет 28193.13-28193.13.

Инструмент: я использовал этот тест регулярных выражений веб-сайт для проверки кода регулярных выражений.

Цените любую помощь.

Можете ли вы отредактировать свой вопрос и показать ожидаемый результат для каждой строки?

anubhava 29.08.2024 13:20

попробуйте этот импорт re text = "28193.13 - 28193.13 / cm" new_text = re.sub(r"[^0-9\.\-]", "", text) я думаю, это должно сработать @ViSa

Hitesh jain 29.08.2024 13:27

@anubhava Я добавил желаемые результаты кейсов

ViSa 29.08.2024 13:27

Попробуйте это решение на Python. ''.join([''.join(x.split()) for x in re.findall(r'\d+(?:\.\d+)?(?: *- *\d+(?:\.\d+)?)*|-', line)])

Wiktor Stribiżew 29.08.2024 13:31

@WiktorStribiżew это почти хорошо .. единственная проблема в том, что он уходит - в последних 4 случаях

ViSa 29.08.2024 13:37

Попробуйте re.sub(r'[^0-9.\-]+', '', text_sample).strip(). Он прошел все дела. Смотрите здесь

underloaded_operator 29.08.2024 13:41

Пожалуйста, проверьте свой вопрос: последние 4 строки содержат дефисы, и вы говорите, что это ожидаемый результат. В противном случае достаточно просто изменить регулярное выражение на re.compile(r'\d+(?:\.\d+)?(?: *- *\d+(?:\.\d+)?)*').

Wiktor Stribiżew 29.08.2024 13:41

@WiktorStribiżew, ты был прав с самого первого раза. Я хотел включить в результат дефис, но допустил ошибку, скопировав ваш ответ. Пожалуйста, укажите свое решение в ответе, чтобы я мог принять ответ, закрыть сообщение и поблагодарить вас за помощь. Большое спасибо за расшифровку.

ViSa 29.08.2024 13:45

Просто интересно: re.sub(r'[^0-9.-]+', '', text_sample).strip() у вас тоже работает?

Wiktor Stribiżew 29.08.2024 13:52

@WiktorStribiżew да, в моих случаях даже это работает

ViSa 29.08.2024 13:55

@WiktorStribiżew есть ли разница в использовании re.compile(r'\d+(?:\.\d+)?(?: *- *\d+(?:\.\d+)?)*') или даже re.sub() и test_df['Range'].str.extract(r"(\d+)(?:\.\d+)?(?: *- *\d+(?:\.\d+)?)*|-") . Потому что эти шаблоны регулярных выражений работали с текстом, но когда я применяю их к dataframe/серии, они не работают.

ViSa 29.08.2024 14:20

@ViSa Вы используете Pandas, так что просто используйте test_df['Range'].str.replace(r'[^0-9.-]+', '', regex=True)

Wiktor Stribiżew 29.08.2024 14:31

@WiktorStribiżew, спасибо. Он работает почти правильно, за исключением первых двух случаев, когда я получаю NAN, вероятно, потому что в первых двух случаях нет -

ViSa 29.08.2024 14:48

Давайте продолжим обсуждение в чате.

ViSa 29.08.2024 14:53
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
14
52
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Я думаю, что это хорошее решение для регулярного выражения.


    # Define the regex pattern to match numbers, decimals, and hyphens
    pattern = r"[\d\.]+(?:-\d+)?"
    # Find all matches
    matches = re.findall(pattern, value)
    # Join matches to form the cleaned value
    cleaned_value = ''.join(matches)
    return cleaned_value

Вы также можете решить это немного более надежно:

def clean_value(value):
    # Filter out characters that are not digits, period, or hyphen
    cleaned_value = ''.join([char for char in value if char.isdigit() or char in ['.', '-']])
    return cleaned_value

# Apply the cleaning function to the data
cleaned_data = [clean_value(val) for val in data]```

Используйте re.sub из встроенной документации по регулярным выражениям (re)

Технически re не является регулярным выражением, но для большинства случаев использования re лучше, поскольку оно встроено в «import re» и не требует установки pip.

Документация по ссылке выше:

Верните строку, полученную путем замены крайних левых непересекающихся вхождений шаблона в строке на замену repl. Если шаблон не найден, строка возвращается без изменений. repl может быть строкой или функцией; если это строка, любые символы обратной косой черты в ней обрабатываются. То есть \n преобразуется в один символ новой строки, \r преобразуется в возврат каретки и т. д. Неизвестные escape-символы ASCII-букв зарезервированы для использования в будущем и рассматриваются как ошибки. Другие неизвестные побеги, такие как &, остались в покое. Обратные ссылки, такие как \6, заменяются подстрокой, соответствующей группе 6 в шаблоне.

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