Регулярное выражение и Unicode для извлечения цены в Python

Я пытаюсь извлечь некоторые цены с веб-сайта ikea, но формат цены довольно грязный (пробел, возврат каретки, запятая в середине нигде). Вот что я извлек:

        39,90 €
                            ,

Я использовал Scrapy, чтобы сделать это, до сих пор никаких проблем, за исключением того, что я хотел бы избавиться от всего, что не является ценой (и символом евро)!

Я пытался использовать это регулярное выражение (в Python 2.7):

re(\S[0-9]+([ ,]?[ ])([0-9]{2}?)u"\u20AC")

Я новичок в программировании, и сегодня я узнал, что такое регулярное выражение, но я попробовал огромное количество возможностей, но не добился лучших результатов, чем:

SyntaxError: unexpected character after line continuation character

Если бы кто-то мог потратить несколько минут, чтобы посмотреть на то, что я сделал, и сказать мне, где я неправ, это было бы здорово!

Ура всем

1 ответ

Решение

Какой тип строк вы пытаетесь сопоставить с юникодом или байтом?

Предположим, что вы работаете со строками Unicode, тогда ваше соответствие может выглядеть так:

#!/usr/bin/python
import re

s = u"""        39,90 \u20AC
                  """
groups = re.match(ur'\D*(\d+)\D*(\d{0,2})\D*(\u20AC)', s, re.UNICODE)
print groups.groups()

выход:

(u'39', u'90', u'\u20ac')

u перед строками указывает, что это строка в кодировке Юникод.

Регекс объяснил:

  1. \ D * - все, что не является цифрой ноль или более раз
  2. (\d+) - одна или несколько цифр
  3. \ D * -...
  4. (\ d {0,2}) - ноль или две цифры
  5. \ D * -...
  6. (\ u20AC) - символ валюты юникода

Мы используем \D, \d вместе с флагом re.UNICODE, чтобы все, что в unicode интерпретировалось как цифра или не цифра, совпадало.

Если вы используете байтовые строки. Я предполагаю, что вы работаете со строкой байтов utf-8. Затем:

import re

s = b"""        39,90 \xE2\x82\xAC
                  """

groups = re.match(r'\D*(\d+)\D*(\d{0,2})\D*(\xE2\x82\xAC)', s)
print groups.groups()

выход:

('39', '90', '\xe2\x82\xac')

"\ xe2 \ x82 \ xac" - это последовательность байтов "e282ac", которая в кодировке utf-8 означает знак евро.

Хорошая практика называется "Unicode бутерброд":

  1. Декодировать байты в Unicode на входе
  2. Работа только с юникодом
  3. Кодировать юникод в байты на выходе
Другие вопросы по тегам