Как использование Regex в Пайтоне 2.7

Я помещаю вас в контекст: Я реализовал пару scripts с регулярными выражениями через модуль re python.

def get_document_emails(pdf_format_content):
    """ The function runs through the document and extracts all the email addresses it finds. 
        This method returns an ordered list of document emails without repeating. """
    new_list = []
    document_emails = re.findall(r'[w.\w]*@w*.[w.\w]*', pdf_format_content)
    for i in document_emails:
        if i not in new_list and not str(i).endswith('.'):
            new_list.append(i)
    return sorted(new_list)

def get_document_provider(pdf_format_content):
    """ Return the name of the provider """
    return re.match(r'(PROVEEDOR:)+(.*?\\n)', pdf_format_content)

Проблема появляется, выполнив вторую функцию. Я использовал библиотеку tika, чтобы извлекать информацию pdf´s и потом призываю в эти функции извлекать электронные почты документа и данные поставщика.

Я протестировал оба регулярных выражения в Regex101 и они захватывают то, в чем я нуждаюсь, в области веб-страницы. Когда я выполняю мои scripts в консоли, с ipython, первый функционирует роскошный но второй не, я протестировал функции findall (), матч (), search (). и все возвращают NoneType или [].

Первая функция работает на цепи unicode, и возвращает без проблем список mails документа, в формате unicode, но вторая функция - нет. Также я попытался кодировать ее, как utf-8, но он дает мне ошибку кодирования в каких-то chars, также обращать ее в String со следующим решением: fpdf = fpdf.encode ('utf-8') .strip (), Но результат - тот же самый, или пустой список или NoneType.

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

То, что больше беспокоит меня, состоит в том, что мне не удается понять почему с электронными почтами, функционирует ли оно, но с другим regex не. Imagen que demuestra que el patrón funciona

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

Ejecución scripts en consola

В этом другом изображении я показываю вывод из-за консоли, удалил чувствительный info, но думаю, что понятно, что я хочу, чтобы вы видели. Если кто-то сможет помогать мне решать это, я ему буду очень благодарен.

Thank you all!!!

Я ИЗДАЮ

После комментариев приятелей и решать регулярное выражение оставляя ее такой r' (ПОСТАВЩИК:) + (.*? \n)' я попытался посмотрим он это решал.

Совсем не дальше реальности, хотя я остаюсь, не понимая, почему первое выражение функционирует и находит результаты и второе выражение не функционирует, на той же переменной, которая содержит текст в формате unicode.

Я присоединяю полный код, который я использую:

# -*- coding: UTF-8 -*-
import re
from tika import parser


def get_pdf_content(path):
    """ Return the text content from the file given through path variable. """
    pdf = parser.from_file(path)
    return pdf['content']

def format_pdf_content(pdf_content):
    """ The method formats the content of the pdf, removes the line breaks and returns a unicode string. """
    variable = filter(lambda i: i != '\r', pdf_content)
    return "".join(variable)

def get_document_emails(pdf_format_content):
    """ The function runs through the document and extracts all the email addresses it finds. 
        This method returns an ordered list of document emails without repeating. """
    new_list = []
    document_emails = re.findall(r'[w.\w]*@w*.[w.\w]*', pdf_format_content)
    for i in document_emails:
        if i not in new_list and not str(i).endswith('.'):
            new_list.append(i)
    return sorted(new_list)

def get_document_provider(pdf_format_content):
    """ Return the name of the provider """
    return re.match(r'(PROVEEDOR:)+(.*?\r)', pdf_format_content)

Большое спасибо снова!!

2
задан 16.01.2019, 07:22
2 ответа

Помимо lГ - или инициал, который tenГ-схвати, если брусок debГ,, - который будьте должен идти двойная порция или нет, tambiГ©n у тебя есть проблема с нею expresiГіn регулировать, что ты используешь, чтобы находить поставщик, и с нею funciГіn пакета re, которые ты используешь для этого.

AsГ - что мы идем по частям.

carГЎcter \

, Хотя я думаю, что это уже осталось ясным, на всякий случай объяснил с mГЎs деталь в continuaciГіn.

Внутри цепи entrecomillada, carГЎcter \ считается специальным и Ваше значение зависит quГ© carГЎcter пойдите detrГЎs Г©l. Если detrГЎs идет одна n, пара \n представляет в действительности один carГЎcter названный "Newline" и которого Американского стандартного кода обмена информацией 13. Если идет одна r, пары \r один sГіlo так называемый характер "carriage Return" и которого Американского стандартного кода обмена информацией 10. Эти два символа обычно оказываются объединенными в порядке \r\n, названные tambiГ©n "CRLF", но завись от оперативного (в Unix он состоит mГЎs обычно в том, что \n мстит только).

, Если detrГЎs \ он оказывается другим \, тогда пара \\ представляет один sГіlo carГЎcter, что является обратным бруском (Американский стандартный код обмена информацией 92). Тот факт, что папки в Windows отделились посредством \, вынуди, чтобы удваивать их, когда они появляются внутри цепи Пайтон.

TambiГ©n в регулярных выражениях carГЎcter \ специальный для самой expresiГіn регулярная, так как обычно служит для того, чтобы выразить categorГ-эксперт символов. Например \d представляет "dГ-gitos". Так как в python регулярные выражения сохраняют в цепях, serГ - в необходимый повторять этот \, когда он используется, чтобы определять categorГ-туз регулярных выражений. AsГ, - expresiГіn регулировать "один или mГЎs dГ-gitos" что serГ - в \d+, в цепи Пайтон escribirГ - ejemplo = "\\d+" (он удваивается, чтобы лишать его Вашего специального siginficado внутри цепи, способа ques и храните sГіlo один. Таким образом len(ejemplo) serГЎ 3, и ejemplo[0] serГ - в carГЎcter \, в то время как ejemplo[1] serГ - в d).

, Если мы не хотим, чтобы у \ было специальное значение в цепи Пайтон, мы можем использовать цепей raw , которые предшествовались одной r. Он это предотвращает быть должным удваивать этот carГЎcter каждый раз, когда он появляется, что может быть Гєtil для Windows маршрутов: ruta = r'C:\Users\abulafia\Documentos\Mi Carpeta\Otra carpeta'. Взамен мы теряем способность выражать возврат каретки, так как r"\n" almacenarГ - в последовательность двух символов \ и n, вместо одного (Американский стандартный код обмена информацией 13).

, Так как в регулярных выражениях используются много \, обычно используют цепей raw , чтобы содержать их и asГ - избегают быть должным удваивать это. AsГ, - она expresiГіn регулировать "последовательность один или mГЎs dГ-gitos" tambiГ©n может писаться как ejemplo = r"\d+", и переменная almacenarГ - в точно то же самое , который в elc поджарил ejemplo = "\\d+".

, Чтобы заканчивать осложнять вещи, expresiГіn регулировать r"\n" содержит в действительности два символа, но механизм регулярных выражений считает, что объединенный два представляют возврат каретки (таким же образом как considear, что значит \d "один dГ-gito"), с которым нет проблемы, в цепей используют raw всегда в регулярных выражениях.

Один lГ - или добавочный происходи, если ты переворачиваешь цепь Пайтон из-за консоли. Пайтон выбирает представлять цепи, когда они перевернуты в формате, который позволял бы "копировать их и прикреплять их" как часть одного cГіdigo. AsГ - что, если ты делаешь ее asignaciГіn:

>>> ejemplo = r"\d+"

и ты переворачиваешь эту переменную, которую нужно видеть quГ©, он содержит:

>>> ejemplo
'\\d+'

Пайтон выбирает показывать ее как caena нормально (когда бы то ни было raw ), разграниченная ' и следовательно с каждыми \, повторенный, так что podrГ-схвати копировать это и распределять это в другую переменную, которая tendrГ - в ту же стоимость, что и переменная ejemplo. Но этот формат вывода запутывает много пользователей, которые думают, что цепь содержит carГЎcter \, повторенные, когда в действительности sГіlo он это содержит однажды, и это - Ваш representaciГіn , который это показывает повторенный.

Она expresiГіn регулировать r'(PROVEEDOR:)+(.*?\r)'

Превышают первых parГ©ntesis, так как я понимаю, что ты не хочешь захватить слово "ПОСТАВЩИКА", а sГіlo найти ее. Вот что ты хочешь захватить, то, что идет despuГ©s ее.

Знак + вслед за этими parГ©ntesis tambiГ©n, кажется, является плохой. Этот знак значит "одна или mГЎs повторения того, что он предшествует ему". Но то, что он предшествует ему, является группой (PROVEEDOR:), что значит, что estarГ-эксперт ища "одна или mГЎs повторения текста "PROVEEDOR:" следовавших", или же, немного как "PROVEEDOR:PROVEEDOR:PROVEEDOR:". В realida, так как случай "один" tambiГ©n допускает, encontrarГ - в как vГЎlido один "PROVEEDOR:", но я предполагаю, что никогда не появляется эта повторенная цепь, а следовательно он превышает +.

QuizГЎs querГ-схвати помещать "Цепь непрерывные "PROVEEDOR:" один или mГЎs место", но в этом случае ты olvidГі помещать место перед +, asГ-: (PROVEEDOR:) +. Хотя это вынуждает, в который было по крайней мере место. Если возможно, что нет ни одного, лучше использовать * вместо +.

В конце концов приходит группа задержания, которое интересует тебя, которое "Любая последовательность символов нечетное число - greedy , до тех пор, пока первый \r не появился. Это tambiГ©n estГЎ плохо, потому что в принципе возможно, что \r он не появляется (зависит от оперативного тот, который этот carГЎcter estГ© или не) и serГ - в mГЎs страховка использовать один \n. И во-вторых, потому что ты не хочешь я (предполагаю), что возврат каретки составляет часть результата, из-за которого лучше estarГ - во вне группы задержания. И уже шага убирать tambiГ©n от группы задержания они hipotГ©ticos место в конце концов.

Следовательно asГ-:

r"PROVEEDOR: *(.*?) *\n"

funciГіn, чтобы использовать

, ты использовал re.match(), но эта funciГіn sГіlo возвращает группу матч , если цепь совпадает с нею expresiГіn регулировать с Вашего начала , что не твой случай в тот, что то, что ты ищешь estГЎ из-за способа.

Для этого случая лучше использовать re.search(), предполагая, что sГіlo был поставщик, или re.findall(), если могут быть некоторые.

Давайте Предполагать, что sГіlo есть один. re.search() buscarГЎ первое происшествие ее expresiГіn регулировать в цепи, и тебе retornarГЎ матч . Г‰ste contendrГЎ полная цепь, для которой случилось совпадение (то, что включает tambiГ©n текст "PROVEEDDOR: " и место и возвраты каретки, которые мы не хотим), и tambiГ©n он содержит группы задержания, которое является тем, что интересует тебя в этом случае, так как группа задержания contendrГЎ то, что является именем поставщика только.

AsГ - так как, ты funciГіn serГ - в:

def get_document_provider(pdf_format_content):
    """ Return the name of the provider """
    m = re.search('PROVEEDOR: *(.*) *\n', pdf_format_content)
    if m:
       return m.groups()[0]
    else:
       return None

добавочная Деталь

она мне не кажется необходимой funciГіn, что удаляет \r.

Также не необходим в действительности включать \n внутри нее expresiГіn регулировать, так как в группе .*? назначенная по умолчанию точка представляет "Любой характер, кроме возврат каретки", так что как только найдет возврат каретки darГ - за законченный матч и группа задержания.

Следовательно создал, что следующее funcionarГЎ также (или quizГЎs лучше):

def get_document_provider(pdf_format_content):
    """ Return the name of the provider """
    m = re.search('PROVEEDOR: *(.*) *', pdf_format_content)
    if m:
       return m.groups()[0]
    else:
       return None
4
ответ дан 20.11.2019, 01:17
  • 1
    Я верю в то, что jamá s мне объяснил что-то довольно так, как ты только что сделал это. Конечно tení в беспорядок с брусками важно, ademá s / cará cter () \n и \r и группы в regex. В конце концов бедствие, которое ты только что решил с этой explicació n такая подробная и структурированная. Muchí пропасти спасибо @abulafia, люди, что actú в бескорыстной формы, чтобы помогать demá s заслуживается все мое уважение, и конечно, tú ты это приобрел полностью. Большое спасибо снова má хина!! TOP –  Borjinha10 16.01.2019, 23:25
  • 2
    Я ты радуюсь тому, что осветлил сомнения. Твой комментарий - для меня лучшее вознаграждение –  abulafia 17.01.2019, 00:52

ты можешь делать это так:
ты группируешь provedor в результате и убегаешь разрыв линии \n с добавочными \\n также ты добавляешь \n к группе результата и не как конечный характер ты должен помещать это так:

return re.findall(r'[PROVEEDOR:]+(.*?)\n', pdf_format_content)

твой код остался бы таким:

def get_document_emails(pdf_format_content):
    """ The function runs through the document and extracts all the email addresses it finds. 
        This method returns an ordered list of document emails without repeating. """
    new_list = []
    document_emails = re.findall(r'[w.\w]*@w*.[w.\w]*', pdf_format_content)
    for i in document_emails:
        if i not in new_list and not str(i).endswith('.'):
            new_list.append(i)
    return sorted(new_list)

def get_document_provider(pdf_format_content):
    """ Return the name of the provider """
    return re.match(r'[PROVEEDOR:]+(.*?)\n', pdf_format_content)
0
ответ дан 20.11.2019, 01:17
  • 1
    Спасибо за комментирование @Bryro!! –  Borjinha10 16.01.2019, 07:05
  • 2
    patró n tení в такое зло как добро indicó @abulafia, но кажется, что уже он был решен. То, что у меня не остается ясным, из-за qué bú squeda первого patró n (электронные почты), если оно функционирует на форматируемом но этом файле, другой не функционирует на той же переменной, попробовав повторять из-за линий в цикле (for линия in файл:) линия равна единственному cará cter а следовательно также не функционирует expresió n регулировать. Я остаюсь, не доставая проблемы. Спасибо за отвечание!!! –  Borjinha10 16.01.2019, 07:12
  • 3
    ты должен издавать вопрос и добавлять больше информации тогда! –  Bryro 16.01.2019, 07:17