Регулярное выражение для захвата до определенного процента / десятичных знаков

1

Я пытаюсь очистить процентные ставки на нескольких сайтах. Данные довольно неструктурированы, но достаточно близки по форме. Что я хочу захватить:

x.xx% до xx.xx%

Примеры того, как выглядят данные:

Все ссуды, предоставленные WebBank, член FDIC. Ваша фактическая ставка зависит от кредитного балла, суммы кредита, срока кредита, использования кредита и истории. APR колеблется от 5,98% до 35,89%. Например, вы могли бы получить кредит в размере 6 000 долларов США с процентной ставкой 7,99% и комиссией за первоначальный взнос в размере 5,00% в размере 300 долларов США за апрель 11,51%. В этом примере вы получите $ 5700 и будете составлять 36 ежемесячных платежей в размере 187,99 долларов США. Общая сумма возмещаемой суммы составит 6 767,64 долл. США. Ваш APR будет определен на основе вашего кредита в момент подачи заявки. Плата за инициирование колеблется от 1% до 6%, а средняя сумма первоначального взноса составляет 5,49% по состоянию на 1 квартал 2017 года. Первоначальный взнос отсутствует, и никогда не будет штрафа за предоплату. Закрытие вашего кредита зависит от вашего согласия всех необходимых соглашений и раскрытия информации на веб-сайте www.lendingclub.com. Все кредиты через LendingClub имеют минимальный срок погашения 36 или более месяцев.

3,09% - 14,24% *

Фиксированные ставки: от 6.99% до 24.99%. Блокировка APR в вашей ставке. Ваш ежемесячный платеж никогда не изменится.

Я выделил то, что хотел захватить. Мое текущее регулярное выражение выглядит так:

(re.findall('(?i)(\d\.\d\d% (?:to|-) \d\d\.\d\d%)

Фактическая цитата выглядит так:

plcompetitors = ['https://www.lendingclub.com/loans/personal-loans',
                'https://www.marcus.com/us/en/personal-loans',
                'https://www.discover.com/personal-loans/',
                'https://www.lightstream.com/',
                'https://www.prosper.com/']

#cycle through links in array until it finds APR rates/fixed or variable using regex
for link in plcompetitors:
    cdate = datetime.date.today()
    l = r.get(link)
    l.encoding = 'utf-8'
    data = l.text
    soup = bs(data, 'html.parser')
    paragraph = soup.find_all(text=re.compile('[0-9]%'))
    for n in paragraph:
        matches = []
        matches.extend(re.findall('(?i)(\d\.\d\d% (?:to|-) \d\d\.\d\d%)', n.string))
        matches.append(cdate.isoformat())
        matches.append(link)
        print(matches)
    paragraph.append(cdate.isoformat())
    paragraph.append(link)

Новый выход:

['5.98% to 35.89%', '2018-06-22', 'https://www.lendingclub.com/loans/personal-loans']
['2018-06-22', 'https://www.lendingclub.com/loans/personal-loans']
['6.99% to 24.99%', '6.99% to 24.99%', '6.99% to 24.99%', '6.99% to 24.99%', '2018-06-22', 'https://www.marcus.com/us/en/personal-loans']
['2018-06-22', 'https://www.marcus.com/us/en/personal-loans']
['2018-06-22', 'https://www.discover.com/personal-loans/']
['2018-06-22', 'https://www.discover.com/personal-loans/']
['2018-06-22', 'https://www.discover.com/personal-loans/']
['6.99% to 24.99%', '2018-06-22', 'https://www.discover.com/personal-loans/']
['2018-06-22', 'https://www.discover.com/personal-loans/']
['2018-06-22', 'https://www.discover.com/personal-loans/']
['2018-06-22', 'https://www.discover.com/personal-loans/']
['2018-06-22', 'https://www.discover.com/personal-loans/']
['2018-06-22', 'https://www.lightstream.com/']
['2018-06-22', 'https://www.lightstream.com/']
['2018-06-22', 'https://www.lightstream.com/']
['2018-06-22', 'https://www.lightstream.com/']
['2018-06-22', 'https://www.lightstream.com/']
['2018-06-22', 'https://www.lightstream.com/']
['2018-06-22', 'https://www.lightstream.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
['2018-06-22', 'https://www.prosper.com/']
Теги:
python-3.x
beautifulsoup

2 ответа

1
Лучший ответ

paragraph = soup.find_all(text=re.compile('(?i)(\d\.\d\d% (?:to|-) \d\d\.\d\d%)')) строка получает все узлы со значениями, соответствующими вашему шаблону. Вы должны извлечь из этих абзацев матчи.

Используйте что-то вроде

matches=[]
for n in paragraph:
    matches.extend(re.findall(pattern, n.string))

Что касается самого шаблона, вы можете использовать

(?i)\d+(?:\.\d+)?%\s*(?:to|-)\s*\d+(?:\.\d+)?%

См. Демо-версию regex. Подробности:

  • (?i) - нечувствительность к регистру включена
  • \d+(?:\.\d+)? - 1+ цифры, которые необязательно сопровождаются . и 1+ цифры
  • % - знак %
  • \s* - 0+ пробелы
  • (?:to|-) - to или -
  • \s*\d+(?:\.\d+)?% - см. выше (короче говоря, пробельные символы, значение int или float, за которым следует %).
1

Изменение: В свете вашего комментария Выполните следующее в Python3, которое должно обрабатывать вашу строку в ASCII по умолчанию:

вход

import re

input = '''All loans made by WebBank, Member FDIC. Your actual rate depends upon credit score, loan amount, loan term, and credit usage & history. The APR ranges from 5.98% to 35.89%. For example, you could receive a loan of $6,000 with an interest rate of 7.99% and a 5.00% origination fee of $300 for an APR of 11.51%. In this example, you will receive $5,700 and will make 36 monthly payments of $187.99. The total amount repayable will be $6,767.64. Your APR will be determined based on your credit at time of application. The origination fee ranges from 1% to 6% and the average origination fee is 5.49% as of Q1 2017. There is no down payment and there is never a prepayment penalty. Closing of your loan is contingent upon your agreement of all the required agreements and disclosures on the www.lendingclub.com website. All loans via LendingClub have a minimum repayment term of 36 months or longer.

3.09% – 14.24%*

Fixed rates: 6.99% to 24.99% APR Lock in your rate. Your monthly payment will never change.'''
#Non-specific regex (I'm cheating)
output = re.findall('[\d]{1,3}\.[\d]+%[\S\s]{0,5}[\d]{1,3}\.[\d]+%', input)
print('output:')
print(output)

#More specific -- you can edit this in several ways
output_1 = re.findall('[\d]{1,3}\.[\d]+%[to\-\s]+[\d]{1,3}\.[\d]+%', input)
print('\noutput_1:')
print(output_1)

#What you need if you copy+paste from Stack into Python2.7.X
output_2 = re.findall('[\d]{1,3}\.[\d]+%[\s]*[to|\-|\xe2\x80\x93]+[\s]*[\d]{1,3}\.[\d]+%', input)
print('\noutput_2 (Python2.X):')
print(output_2)

Выход

output:
['5.98% to 35.89%', '3.09% - 14.24%', '6.99% to 24.99%']

output_1:
['5.98% to 35.89%', '3.09% - 14.24%', '6.99% to 24.99%']

output_2 (Python2.X)::
['5.98% to 35.89%', '3.09% \xe2\x80\x93 14.24%', '6.99% to 24.99%']
  • 0
    Я вижу, что вы пытаетесь сделать. Если вы посмотрите на комментарии, то один из Wiktor похож на то, что вы пытаетесь сделать, но немного более динамичен, поскольку он может проходить по списку. Благодарю за ваш ответ. Я очень ценю это.
  • 0
    Нет проблем. Не уверен, что я полностью понимаю вопрос. Но, надеюсь, другой может дать лучший ответ. Тем не менее, что вы пытаетесь захватить конкретно? Можете ли вы включить «список» выходных данных, чтобы я мог получить лучшую идею.
Показать ещё 2 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню