Как написать регулярное выражение на python, чтобы найти значения между 2 и 2 000 000 000? - PullRequest
0 голосов
/ 09 января 2019

Я пытаюсь написать регулярное выражение, которое найдет значения валют в моем тексте. У меня есть значения, которые варьируются от 2 долларов до 2 240 000 000. Я пытаюсь написать выражение регулярного выражения, которое найдет все эти значения, но я терплю неудачу. Я пробовал что-то вроде:

^\{USD}?(\d*(\d\.?|\.\d{1,2}))$

но не сработало. Я ценю любую помощь:)

РЕДАКТИРОВАТЬ: Для пояснения у меня есть текст с несколькими долларовыми значениями в диапазоне от 2 до 2 000 000 000.

Текст выглядит примерно так:

"Базовая покупка составляет 2,00 доллара США. (...) Сумма, равная 2 300 000 долларов США, которая относится к премиальному пакету. (...) Стране необходимо 300,00 долларов США ..."

Я хочу найти и извлечь эти значения (доллары США + цифры) и сохранить их в виде списка, каждое из которых является отдельным элементом. Спасибо

Ответы [ 2 ]

0 голосов
/ 09 января 2019

Хорошо, давайте начнем с

import re
text = "The base purchase is USD 2,00.00 (...) The amount equal to US 2,300,000 which refers to the premium package. (...) The country needs USD 300,00..."

Как и предложил @zakinster, вы можете найти интересующие вас строковые числа:

regex = r"(?:USD)?(?:\d+,)*\d+(?:\.\d+)?"
numbers = re.findall(regex, text)

Затем, чтобы отфильтровать упомянутое вами:

def toInteger(s): return int(s.split('.')[0].replace(',',''))

def numberBetween(string,lowerBound,upperBound): 
    intValue = toInteger(string)
    return True if intValue>lowerBound & intValue<upperBound else False

print(list(filter(lambda x: numberBetween(x,2,2240000000),numbers)))

должен дать вам то, что вы хотите:

['2,00.00', '2,300,000', '300,00']
0 голосов
/ 09 января 2019

Множество вещей неправильны в вашем выражении: ^\{USD}?(\d*(\d\.?|\.\d{1,2}))$

  1. \{USD}? в языке регулярных выражений это будет означать: ожидать буквального символа {, за которым следует USD, за которым следует символ }, если таковой имеется. Если вы хотите иметь необязательную группу USD, вы должны использовать круглые скобки без \: (USD)?. Для этого вы можете использовать группу без захвата : (?:USD)?.

Это даст: ^(USD)?(\d*(\d\.?|\.\d{1,2}))$

  1. (\d\.?|\.\d{1,2}), вся группа должна быть повторена, чтобы соответствовать всей строке: (\d\.?|\.\d{1,2})*

Это даст: ^(USD)?(\d*(\d\.?|\.\d{1,2})*)$

  1. \d\.?: если предполагается, что часть соответствует разделителю тысяч, это должна быть запятая, а не точка в вашем примере: \d*,?

Это даст: ^(USD)?(\d*(\d,?|\.\d{1,2})*)$

  1. (\d*(\d: это не сработает, второе \d никогда не будет совпадать, поскольку все цифры будут использованы первым \d*, вы можете использовать не жадный оператор ?, например: (\d*?(\d но это не красиво.

Это даст: ^(USD)?(\d*?(\d,?|\.\d{1,2})*)$, что может сработать для вас, но выглядит неоптимально.

Альтернативой может быть создание регулярного выражения без предложения "или" с использованием следующих частей:

  1. Префикс: "USD", необязательный и с дополнительным пробелом: (USD ?)?
  2. Неотъемлемая часть суммы перед тысячей разделителей: \d+
  3. Неотъемлемая часть суммы с разделителем тысяч, необязательная и повторяемая: (,\d+)*
  4. Десятичная часть, необязательно: (\.\d+)?

Который дал бы что-то подобное: (USD ?)?(\d+)(,\d+)*(\.\d+)?

Вы можете проверить это на regex101.com

Вы можете дополнительно ограничить количество цифр в каждой части, чтобы избежать ложноположительного результата:

(USD ?)?(\d{1,3})(,\d{3})*(\.\d{1,2})?

Окончательная версия будет оптимизирована с не захватывающими группами , если это не необходимо:

(?:USD ?)?(?:\d{1,3})(?:,\d{3})*(?:\.\d{1,2})?

Редактировать: предоставленный вами тестовый пример использует некогерентное использование десятичных разделителей (иногда ".", Иногда ","). Если вы действительно хотите соответствовать этому, вы можете использовать класс символов следующим образом:

(?:USD ?)?(?:\d{1,3})(?:,\d{3})*(?:[.,]\d{1,2})?

Что соответствует каждому числу в вашем примере: Regex 101 screenshot

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...