返回介绍

7.15 项目:电话号码和 E-mail 地址提取程序

发布于 2024-01-22 21:44:06 字数 4979 浏览 0 评论 0 收藏 0

假设你有一个无聊的任务,要在一篇长的网页或文章中,找出所有电话号码和邮件地址。如果手动翻页,可能需要查找很长时间。如果有一个程序,可以在剪贴板的文本中查找电话号码和E-mail地址,那你就只要按一下Ctrl-A选择所有文本,按下Ctrl-C将它复制到剪贴板,然后运行你的程序。它会用找到的电话号码和E-mail地址,替换掉剪贴板中的文本。

当你开始接手一个新项目时,很容易想要直接开始写代码。但更多的时候,最好是后退一步,考虑更大的图景。我建议先草拟高层次的计划,弄清楚程序需要做什么。暂时不要思考真正的代码,稍后再来考虑。现在,先关注大框架。

例如,你的电话号码和E-mail地址提取程序需要完成以下任务:

· 从剪贴板取得文本。

· 找出文本中所有的电话号码和E-mail地址。

· 将它们粘贴到剪贴板。

现在你可以开始思考,如何用代码来完成工作。代码需要做下面的事情:

· 使用pyperclip模块复制和粘贴字符串。

· 创建两个正则表达式,一个匹配电话号码,另一个匹配E-mail地址。

· 对两个正则表达式,找到所有的匹配,而不只是第一次匹配。

· 将匹配的字符串整理好格式,放在一个字符串中,用于粘贴。

· 如果文本中没有找到匹配,显示某种消息。

这个列表就像项目的路线图。在编写代码时,可以独立地关注其中的每一步。每一步都很好管理。它的表达方式让你知道在Python中如何去做。

第1步:为电话号码创建一个正则表达式

首先,你需要创建一个正则表达式来查找电话号码。创建一个新文件,输入以下代码,保存为phoneAndEmail.py:

#! python3
# phoneAndEmail.py - Finds phone numbers and email addresses on the clipboard.

import pyperclip, re

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)

# TODO: Create email regex.

# TODO: Find matches in clipboard text.

# TODO: Copy results to the clipboard.

TODO注释仅仅是程序的框架。当编写真正的代码时,它们会被替换掉。

电话号码从一个“可选的”区号开始,所以区号分组跟着一个问号。因为区号可能只是3个数字(即\d{3}),或括号中的3个数字(即(\d{3})),所以应该用管道符号连接这两部分。可以对这部分多行字符串加上正则表达式注释# Area code,帮助你记忆(\d{3}|(\d{3}))?要匹配的是什么。

电话号码分割字符可以是空格(\s)、短横(-)或句点(.),所以这些部分也应该用管道连接。这个正则表达式接下来的几部分很简单:3个数字,接下来是另一个分割符,接下来是4个数字。最后的部分是可选的分机号,包括任意数目的空格,接着ext、x或ext.,再接着2到5位数字。

第2步:为E-mail地址创建一个正则表达式

还需要一个正则表达式来匹配E-mail地址。让你的程序看起来像这样:

 #! python3
 # phoneAndEmail.py - Finds phone numbers and email addresses on the clipboard.
 import pyperclip, re

 phoneRegex = re.compile(r'''(
 --_snip_--

 # Create email regex.
 emailRegex = re.compile(r'''(
❶     [a-zA-Z0-9._%+-]+         # username
❷     @                     # @ symbol
❸     [a-zA-Z0-9.-]+         # domain name
     (\.[a-zA-Z]{2,4})     # dot-something
     )''', re.VERBOSE)
 
 # TODO: Find matches in clipboard text.

 # TODO: Copy results to the clipboard.

E-mail地址的用户名部分❶是一个或多个字符,字符可以包括:小写和大写字母、数字、句点、下划线、百分号、加号或短横。可以将所有这些放入一个字符分类:[a-zA-Z0-9._%+-]。

域名和用户名用@符号分割❷,域名❸允许的字符分类要少一些,只允许字母、数字、句点和短横:[a-zA-Z0-9.-]。最后是“dot-com”部分(技术上称为“顶级域名”),它实际上可以是“dot-anything”。它有2到4个字符。

E-mail地址的格式有许多奇怪的规则。这个正则表达式不会匹配所有可能的、有效的E-mail地址,但它会匹配你遇到的大多数典型的电子邮件地址。

第3步:在剪贴板文本中找到所有匹配

既然已经指定了电话号码和电子邮件地址的正则表达式,就可以让 Python的re模块做辛苦的工作,查找剪贴板文本中所有的匹配。pyperclip.paste()函数将取得一个字符串,内容是剪贴板上的文本,findall()正则表达式方法将返回一个元组的列表。

让你的程序看起来像这样:

 #! python3
 # phoneAndEmail.py - Finds phone numbers and email addresses on the clipboard.

 import pyperclip, re

 phoneRegex = re.compile(r'''(
 --_snip_--

 # Find matches in clipboard text.
 text = str(pyperclip.paste())
❶ matches = []
❷ for groups in phoneRegex.findall(text):
     phoneNum = '-'.join([groups[1], groups[3], groups[5]])
     if groups[8] != '':
         phoneNum += ' x' + groups[8]
     matches.append(phoneNum)
❸ for groups in emailRegex.findall(text):
     matches.append(groups[0])
 
 # TODO: Copy results to the clipboard.

每个匹配对应一个元组,每个元组包含正则表达式中每个分组的字符串。回忆一下,分组0匹配整个正则表达式,所以在元组下标0处的分组,就是你感兴趣的内容。

在❶处可以看到,你将所有的匹配保存在名为matches的列表变量中。它从一个空列表开始,经过几个for循环。对于E-mail地址,你将每次匹配的分组0添加到列表中❸。对于匹配的电话号码,你不想只是添加分组0。虽然程序可以“检测”几种不同形式的电话号码,你希望添加的电话号码是唯一的、标准的格式。phoneNum变量包含一个字符串,它由匹配文本的分组1、3、5和8构成❷。(这些分组是区号、前3个数字、后4个数字和分机号。)

第4步:所有匹配连接成一个字符串,复制到剪贴板

现在,E-mail地址和电话号码已经作为字符串列表放在matches中,你希望将它们复制到剪贴板。pyperclip.copy()函数只接收一个字符串值,而不是字符串的列表,所以你在matches上调用join()方法。

为了更容易看到程序在工作,让我们将所有找到的匹配都输出在终端上。如果没有找到电话号码或E-mail地址,程序应该告诉用户。

让你的程序看起来像这样:

#! python3
# phoneAndEmail.py - Finds phone numbers and email addresses on the clipboard.

--_snip_--
for groups in emailRegex.findall(text):
matches.append(groups[0])

# Copy results to the clipboard.
if len(matches) > 0:
    pyperclip.copy('\n'.join(matches))
    print('Copied to clipboard:')
    print('\n'.join(matches))
else:
    print('No phone numbers or email addresses found.')

第5步:运行程序

作为一个例子,打开你的Web浏览器,访问No Starch Press的联系页面http://www.nostarch.com/contactus.htm。按下Ctrl-A选择该页的所有文本,按下Ctrl-C将它复制到剪贴板。运行这个程序,输出看起来像这样:

Copied to clipboard:
800-420-7240
415-863-9900
415-863-9950
info@nostarch.com
media@nostarch.com
academic@nostarch.com
help@nostarch.com

第6步:类似程序的构想

识别文本的模式(并且可能用sub()方法替换它们)有许多不同潜在的应用。

· 寻找网站的URL,它们以http://或https://开始。

· 整理不同日期格式的日期(诸如3/14/2015、03-14-2015和2015/3/14),用唯一的标准格式替代。

· 删除敏感的信息,诸如社会保险号或信用卡号。

· 寻找常见打字错误,诸如单词间的多个空格、不小心重复的单词,或者句子末尾处多个感叹号。它们很烦人!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文