Правильный шаблон регулярного выражения (re) в python

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

Данные:

  • Компания Fragile9 закрывает финансирование серии B на 9 млн евро
  • Appplle21 получает 17,5 тыс. канадских долларов в виде долевого финансирования
  • Cat привлекает $10,8 млн в рамках серии финансирования A
  • Sun привлекает финансирование в размере 35 миллионов евро при оценке в 1 миллиард долларов
  • Japan1337 объявляет о раунде финансирования в размере 1,78 миллиарда иен

Из этих данных мне нужно только извлечь сумму денег, которую получает компания (включая $/€ и т. д., а также указание валюты, если она есть, например, канадские доллары (CAD)).

Итак, в результате я ожидаю получить это:

  • 9 миллионов евро
  • 17,5 тыс. канадских долларов
  • 10,8 миллионов долларов
  • 35 миллионов евро
  • 1,78 миллиарда иен

Шаблон, который я использую (кидайте в меня тухлыми помидорами):

try:
    pattern = '(\bAU|\bUSD|\bUS|\bCHF)*\s*[\$\€\£\¥\₣\₹\?]\s*\d*\.?\d*\s*(K|M)*[(B|M)illion]*'
    raises = re.search(pattern, text, re.IGNORECASE) # text – a row of data mentioned above
    raises = raises.group().upper().strip()
    print(raises)
except:
    raises = '???'
    print(raises)

Кроме того, иногда шаблон, который работает в онлайн-редакторе регулярных выражений Python, не будет работать в реальном скрипте.

Можете ли вы показать пример, когда он работает онлайн, но не в вашем скрипте?

mkrieger1 13.02.2023 20:52

Привет @mkrieger1, Просмотрев множество материалов о регулярных выражениях, я попытался создать другой шаблон (не тот, который продемонстрирован выше), и для случая, когда он работал в Интернете, в сценарии произошел сбой. К сожалению, я не сохранил этот шаблон из-за этого сбоя

classicandy 13.02.2023 21:04

Какая валюта ?

trincot 13.02.2023 21:26

Привет, @trincot. Вот как я пытался сказать шаблону, что эти валюты являются переменными. Например, если у меня есть что-то вроде «... 1,78 миллиарда иен ...», знака валюты нет. Я так понимаю, что нужно поставить "?" пометить где-то за скобками, но когда я это сделал, это нарушило шаблон

classicandy 13.02.2023 21:30
Почему в 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 может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Некоторые проблемы в вашем регулярном выражении:

  • Список валютных сокращений (AU USD US CHF) слишком ограничен. Он не будет соответствовать JPY или многим другим аббревиатурам. Может быть, допустим любое слово из 2-3 прописных букв.

  • Не проблема, но символы валюты не нужно экранировать обратной косой чертой.

  • \? в списке валют не является символом валюты.

  • Для регулярного выражения требуется как аббревиатура валюты, так и символ валюты. Возможно, вы намеревались сделать символ валюты необязательным с помощью \?, но тогда ? должен отображаться без экранирования после класса символов, и все же должна быть возможность не использовать аббревиатуру и использовать только символ.

  • Регулярное выражение требует, чтобы число имело десятичные дроби. Это следует сделать необязательным.

  • (K|M)* позволит KKKKKKK. Вы не хотите * здесь.

  • [(B|M)illion]* позволит буквам BMilon, вертикальной черте и скобкам встречаться в любом порядке и в любом количестве. Как будто это будет соответствовать "in" и "non" и "(BooM)"

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

  • Регулярное выражение не обеспечивает сопоставление последней буквы «s» в «миллионах».

Вот поправка:

(?:\b[A-Z]{2,3}\s*[$€£¥₣₹]?|[$€£¥₣₹])\s*\d+(?:\.\d+)?(?:\s*(?:K|[BM](?:illions?)?)\b)?

На регулярном выражении101

В синтаксисе Python:

pattern = r"(?:\b[A-Z]{2,3}\s*[$€£¥₣₹]?|[$€£¥₣₹])\s*\d+(?:\.\d+)?(?:\s*(?:K|[BM](?:illions?)?)\b)?"

Простите, что снова вас беспокою, сэр, но это именно то, что я сказал в комментарии выше, когда какой-то паттерн работает онлайн, но не работает в скрипте. Я попробовал ваш паттерн в действии, и он мне показывает вот это (не ловит "М", "Миллион" и другие, а также если валюта указана буквами "JPY" т.е. показывает как "Нет"): ️ 🔁 imgur.com/a/9HrquLl

classicandy 14.02.2023 14:55

Вы должны избегать обратной косой черты в строковых литералах или использовать r-строки (предпочтительно). Это действительно обычная практика при определении строковых литералов регулярных выражений. Смотрите дополнение к ответу.

trincot 14.02.2023 15:06

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

Как я могу преобразовать двойные косые черты в R, не сталкиваясь с ошибкой, связанной с escape-символами?
JavaScript Буквенно-цифровое регулярное выражение и разрешить звездочку в начале строки, но не разрешать звездочку в последних 4 цифрах строки
Python/regex: соответствует только букве или букве, за которой следует число
Регулярное выражение для форматирования электронной почты без hypen в начале и в конце
Как написать регулярное выражение, которое удаляет любой символ или символ, стоящий перед диапазоном указанных разделителей "(" и ")]"
Поиск по первым буквам фразы - как vscode
Удаление всех экземпляров строки, которая не находится в круглых скобках
Понимание списка с помощью регулярных выражений в текстовом файле Python
Регулярное выражение в скрипте Google для получения цифр после определенных слов
Как преобразовать несколько столбцов вместе с похожими именами в R?