Я пытаюсь придумать правильный шаблон регулярного выражения (и у меня это очень плохо получается) для строк, которые у меня есть. Каждый раз я получаю что-то, что работает только частично. Я покажу шаблон, который я сделал позже, ниже, но сначала я хочу указать, что я хочу извлечь из текста.
Данные:
Из этих данных мне нужно только извлечь сумму денег, которую получает компания (включая $/€ и т. д., а также указание валюты, если она есть, например, канадские доллары (CAD)).
Итак, в результате я ожидаю получить это:
Шаблон, который я использую (кидайте в меня тухлыми помидорами):
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, Просмотрев множество материалов о регулярных выражениях, я попытался создать другой шаблон (не тот, который продемонстрирован выше), и для случая, когда он работал в Интернете, в сценарии произошел сбой. К сожалению, я не сохранил этот шаблон из-за этого сбоя
Какая валюта ?
Привет, @trincot. Вот как я пытался сказать шаблону, что эти валюты являются переменными. Например, если у меня есть что-то вроде «... 1,78 миллиарда иен ...», знака валюты нет. Я так понимаю, что нужно поставить "?" пометить где-то за скобками, но когда я это сделал, это нарушило шаблон
Некоторые проблемы в вашем регулярном выражении:
Список валютных сокращений (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
Вы должны избегать обратной косой черты в строковых литералах или использовать r-строки (предпочтительно). Это действительно обычная практика при определении строковых литералов регулярных выражений. Смотрите дополнение к ответу.
Можете ли вы показать пример, когда он работает онлайн, но не в вашем скрипте?