Я не очень хорошо разбираюсь в регулярных выражениях и пытаюсь, но не могу извлечь только 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
.
Инструмент: я использовал этот тест регулярных выражений веб-сайт для проверки кода регулярных выражений.
Цените любую помощь.
попробуйте этот импорт re text = "28193.13 - 28193.13 / cm" new_text = re.sub(r"[^0-9\.\-]", "", text) я думаю, это должно сработать @ViSa
@anubhava Я добавил желаемые результаты кейсов
Попробуйте это решение на Python. ''.join([''.join(x.split()) for x in re.findall(r'\d+(?:\.\d+)?(?: *- *\d+(?:\.\d+)?)*|-', line)])
@WiktorStribiżew это почти хорошо .. единственная проблема в том, что он уходит -
в последних 4 случаях
Попробуйте re.sub(r'[^0-9.\-]+', '', text_sample).strip()
. Он прошел все дела. Смотрите здесь
Пожалуйста, проверьте свой вопрос: последние 4 строки содержат дефисы, и вы говорите, что это ожидаемый результат. В противном случае достаточно просто изменить регулярное выражение на re.compile(r'\d+(?:\.\d+)?(?: *- *\d+(?:\.\d+)?)*')
.
@WiktorStribiżew, ты был прав с самого первого раза. Я хотел включить в результат дефис, но допустил ошибку, скопировав ваш ответ. Пожалуйста, укажите свое решение в ответе, чтобы я мог принять ответ, закрыть сообщение и поблагодарить вас за помощь. Большое спасибо за расшифровку.
Просто интересно: re.sub(r'[^0-9.-]+', '', text_sample).strip()
у вас тоже работает?
@WiktorStribiżew да, в моих случаях даже это работает
@WiktorStribiżew есть ли разница в использовании re.compile(r'\d+(?:\.\d+)?(?: *- *\d+(?:\.\d+)?)*')
или даже re.sub()
и test_df['Range'].str.extract(r"(\d+)(?:\.\d+)?(?: *- *\d+(?:\.\d+)?)*|-")
. Потому что эти шаблоны регулярных выражений работали с текстом, но когда я применяю их к dataframe/серии, они не работают.
@ViSa Вы используете Pandas, так что просто используйте test_df['Range'].str.replace(r'[^0-9.-]+', '', regex=True)
@WiktorStribiżew, спасибо. Он работает почти правильно, за исключением первых двух случаев, когда я получаю NAN
, вероятно, потому что в первых двух случаях нет -
Давайте продолжим обсуждение в чате.
Я думаю, что это хорошее решение для регулярного выражения.
# 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 в шаблоне.
Можете ли вы отредактировать свой вопрос и показать ожидаемый результат для каждой строки?