#python #regex
#python #регулярное выражение
Вопрос:
Я учусь программировать на python, используя книгу automate the boring stuff. Один из проектов заключается в использовании регулярных выражений для извлечения информации из таблицы данных. Код, приведенный в книге, работает плохо, я думаю, что данные примера изменились, поэтому я адаптировал код для удаления ошибок.
Пример ошибок — извлеченный адрес электронной почты — 1852nvinson8@hotmail.com извлеченное имя — Коммилтон Уэйд
Я добавил пару строк, чтобы удалить com / net в имени и 4 цифры в начале адреса электронной почты.
(d{4}) # cheat code to remove digits
([A-Z][a-z] ) # starts with capital - first name
Есть ли лучший способ извлечь данные без добавления кода для удаления ошибок?
Пример данных примера
Norbert Vinson385-868-1852nvinson8@hotmail.comMilton Wade931-883-8104mwade90@gmail.comLauren Barnett573-991-4106lbarnett80@sbcglobal.netCary Kirby859-271-7097ckirby9@msn.comBiostatisticianClark Salinas845-641-5553csalinas16@mac.comOfficerHugo Cross500-760-4858hcross@optonline.netAssistantDomenic Molina256-975-9610dmolina@me.com
мой код
import re, pyperclip
# create regex for name
nameRegex = re.compile(r'''(
([A-Z][a-z] ) # starts with capital - first name
s # space
([a-zA-Z] ) # last name
)''', re.VERBOSE)
# Create a regex for phone numbers
# 415-555-0000, 555-0000, (415) 555-0000, 555-0000 ext 12345, ext. 12345, x12345
phoneRegex = re.compile(r'''(
(d{3}|(d{3}))? # area code
(s|-|.)? # separator
(d{3}) # first 3 digits
(s|-|.) # separator
(d{4}) # last 4 digits
(s*(ext|x|ext.)s*(d{2,5}))? # extension
)''', re.VERBOSE)
# Create a regex for email addresses
# some. _thing@something.com
emailRegex = re.compile(r'''(
(d{4}) # cheat to remove digits
([a-zA-Z0-9_. ] ) # name part
(@ ) # @ symbol
([a-zA-Z0-9_. ] ) # domain name
(.com|.net ) # cheat for TLD
# Find all Matches in the Clipboard Text
text = str(pyperclip.paste())
matches = []
for groups in nameRegex.findall(text):
matches.append(groups[0])
for groups in phoneRegex.findall(text):
phoneNumbers = '-'.join([groups[1],groups[3], groups[5]])
matches.append(phoneNumbers)
for groups in emailRegex.findall(text):
emailAddress = ''.join([groups[2],groups[3],groups[4],groups[5]])
matches.append(emailAddress)
# print the extracted email/phone
if len(matches) > 0:
print('n'.join(matches))
else:
print('No phone numbers or email addresses found.')
print(matches)
Комментарии:
1. вы можете использовать просто (.*) вместо ([a-zA-Z0-9_. ] )
Ответ №1:
Я могу предложить вам этот способ извлечения данных «одно правило, чтобы управлять ими всеми» 🙂
(?P<Position>[A-Z][a-z] ){0,}(?P<FullName>(?P<FirstName>[A-Z][a-z] )s(?P<LastName>[A-Z][a-z] ))(?P<SocialNumber>d{3}-d{3}-d{4})(?P<email>[w.-] @[w] .[a-z] )
вы можете попробовать его в живом виде наhttps://regex101.com/r/h7kW07/1
кстати, если вы попытаетесь создать новую учетную запись электронной почты в yahoo с вашим примером (некоторые. thing@something.com ), он завершится ошибкой: «Вы можете использовать только буквы, цифры, точки (‘.’) и подчеркивания (‘’) в вашем имени пользователя». Таким образом, хорошим шаблоном для этого случая будет ([ w.] )
p.s. он не будет передавать электронные письма с ‘ ‘
Ответ №2:
Поскольку разные желаемые части (например, должность, имя, номер, адрес электронной почты) связаны друг с другом, было бы эффективнее извлечь их все, используя один шаблон, который может быть:
(?P<POS>[A-Z][a-z] )?(?P<NME>(?:[A-Z][a-zs] ) )(?P<NUM>(?:d -?) )(?P<EML>w @w (?:.com|.net))
Вы можете попробовать это в интерактивном режиме на следующем веб-сайте: