Я пытаюсь очистить процентные ставки на нескольких сайтах. Данные довольно неструктурированы, но достаточно близки по форме. Что я хочу захватить:
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/']
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, за которым следует %
).Изменение: В свете вашего комментария Выполните следующее в 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%']