在这篇文章中,我们将看到如何使用Python从一个文本文件中提取电子邮件。为了使事情更容易使用,我们将使用一些**正则表达式。**这些是一些特殊的字符方程,甚至在计算机出现之前的很长一段时间内就已经被用于字符串操作了。
在 Python 中使用 RegEx
当我们需要处理一个字符串并为我们的输出创建一个好的格式时,正则表达式这个术语意义重大。re " 模块是Python中的一个内置模块。在各小节中,我们将看到基本的操作,然后转向主要的话题。
正则表达式的应用
为了得到一个更清晰的概念,这里有一些应用:
- 在一个字符串中找到一个特定的模式。
- 匹配一个句子中的特定关键词或字母。
- 从一个长文本中提取有用的符号或模式。
- 执行复杂的字符串操作。
关于RegEx Python库的一个小教程
正则表达式允许我们在给定的文本中匹配一个特定的模式。因此,为了使事情变得更容易,我们将在这个话题中了解它们。正则表达式不仅适用于电子邮件提取,而且还适用于大数据中文本的ETL(提取、转换和加载)处理,它已经使用了很长时间。
有四个基本函数可以对字符串进行四种基本操作:
- match()。在文本的开头匹配一个特定的字符串模式。
- find()。在给定的文本中找到一个字符串模式。
- findall()。找到整个文本中所有匹配的字符串。
- finditer()。找到一个匹配的模式,并将其作为一个可迭代的对象返回。
对特殊字符匹配的限制
有一组特殊字符不参与匹配,而是帮助寻找字符串中的复杂模式。下面是这些字符的列表。
- 方括号: [ ]
- 圆括号:( )
- 大括号:{ }
- 管子:|
- 反斜线:\
- 问号:?
- 加号 : +
- 点运算符:"."
- 排他性OR(XOR)运算符:^
- 截断符号:$
- 星号或星形运算符:*
要记住的一点。还要注意的是,每当匹配一个模式时,我们必须在声明一个字符串之前用 "r "字母指定它为一个原始字符串。这使得Python的RegEx引擎能够避免任何类型的错误。例如:myPattern = r "myString"。
编译一个正则表达式
开始字符串操作的第一件事是我们需要将我们的表达式编译到我们的系统中。这将创建一个对象,帮助我们调用上述四个函数。为了编译一个表达式,我们使用re.compile()函数并在该函数中插入我们的模式。将标志设置为re.UNICODE。
代码
import re
myPattern = re.compile("python", flags = re.UNICODE)
print(type(myPattern))
输出
<class 're.Pattern'>
现在我们已经成功创建了一个模式对象。使用这个对象,我们将调用函数并执行所有的操作。
match()函数
如果字符串的起始字符与模式匹配,该函数将创建一个对象。
代码
match = myPattern.match("python")
print(match.group())
输出
python
调用该组函数时,我们可以指定是否。因此,当模式与我们的样本字符串匹配时,那么对象就会被创建。我们可以使用**span()**函数检查匹配的索引。
print("The pattern matches upto {0}".format(match.span()))
The pattern matches upto (0, 6)
请记住,如果该函数没有找到任何匹配,那么就不会有对象被创建。 我们得到一个NoneType作为返回答案。match() function 以一个元组的形式返回匹配的字符串索引位置。它也有两个额外的参数,即:
- pos:匹配文本/字符串的起始位置/索引。
- endpos:起始文本的结束位置/索引。
例子
match = myPattern.match("hello python", pos = 6)
print(match.group())
print("The pattern matches upto {0}".format(match.span()))
# output
python
The pattern matches upto (6, 12)
提前匹配实体
有时我们的字符串可能包含一些数字、数码、空格、字母数字字符等。因此,为了使事情更加可靠,Ren有一些签名集。我们需要在我们的原始字符串中指定这些。
- \d:匹配从0到9的整数字符 。
- \D:匹配从0到9的非整数字符。
- \s:用于任何空白字符。"\n", "\t", "\r"
- \S:适用于任何非空白字符。
- \w:匹配字母数字字符。
- \匹配任何非字母数字字符。
匹配函数的标志。
当我们进行某种复杂的文本分析时,标志证明是一种额外的帮助。因此,下面是一些标志的列表。
- re.ASCII或re.A:对于所有ASCII编码的字符,如。\w, \W, \b, \B, \d, \D, \s 和 \S 。
- re.DEBUG。显示所有的调试信息。
- re.IGNORECASE或re.I:这个标志执行不区分大小写的匹配。
- re.MULTILINE或re.M:在匹配开始或结束模式后立即进行换行。
search()函数
搜索函数在一个字符串中搜索一个特定的模式/单词/字母/字符,如果找到该模式,则返回该对象。
import re
pattern = r"rain rain come soon, come fast, make the land green";
mySearch = re.search("rain", pattern, re.IGNORECASE))
print("Successfully found, ", mySearch.group(), " from", mySearch.start(), " to ",mySearch.end())
#output
Successfully found "rain" from 0 to 4
使用RegEx 模块提取电子邮件
由于我们已经学习了所有的基础知识,现在是时候迎接更大的挑战了。让我们在一段代码中实现文件读取和正则表达式的知识,并从该文件中提取一些电子邮件地址。
样本文件
Hello my name is Tom the cat.
I like to play and work with my dear friend jerry mouse.
We both have our office and email addresses also.
They are tomcat@gmail.com, jerrymouse@gmail.com.
Our friend spike has also joined us in our company.
His email address is spikethedog@gmail.com.
We all entertaint the children through our show.
这里是一个包含三个电子邮件地址的简单文件。这也使事情变得更加复杂,但是,我们的代码将使它们更加简单。使用上述关于正则的知识,我们可以很好地实现它。
这方面的正则表达式是:“[0-9a-zA-z][email protected][0-9a-zA-z]+\.[0-9a-zA-z]+”
代码
import re
try:
file = open("data.txt")
for line in file:
line = line.strip()
emails = re.findall("[0-9a-zA-z]+@[0-9a-zA-z]+\.[0-9a-zA-z]+", line)
if(len(emails) > 0):
print(emails)
except FileNotFoundError as e:
print(e)
解释一下
- 该模式表示:提取以字母数字字符开始并有"@"符号的文本,之后又有字母数字字符并有一个点".",在这个点之后又有相同类型的字符。
- 不要直接使用这个点,**而是用反斜杠"/. "包括它,**以指定Python重构引擎我们正在使用这个点。使用它将指定我们在模式中使用除换行之外的每个字符。
- 然后将样本文本包含在一个文件中。
- 在阅读模式下打开该文件。
- 用一个行变量实现一个for循环。它读取文本中的每一行。
- 然后剥离行,提取文本的每个部分。
- 创建一个findall() 函数的对象,并在其中包括我们的模式表达式,然后包括行变量。这段代码将文本的每一条都与模式相匹配。
- 在模式匹配后,它只是打印出来。
- 外面的代码只是一个处理错误的try-catch块。
输出
['tomcat@gmail.com', 'jerrymouse@gmail.com']
['spikethedog@gmail.com']
结论
因此,我们用几行代码实现了一个智能脚本,从一个给定的文本中提取电子邮件。