让我们来看一个无结构的示例文件:
this is a test
fred is fred@foo.com and joe is joe@example.com - but
@this is a twitter handle for twit@here.com
然后,如果你执行以下操作:
myText <- readLines("testmail.txt")
emails = unlist(regmatches(myText, gregexpr("([_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,4}))", myText)))
> emails
[1] "fred@foo.com" "joe@example.com" "twit@here.com"
它提取了包括同一行有多个电子邮件地址的所有电子邮件地址向量。我认为它不会找到跨行断开的电子邮件地址,但如果您将读取的行粘贴在一起,它也可能找到这种情况:
> myText = paste(readLines("testmail.txt"),collapse=" ")
> emails = regmatches(myText, gregexpr("([_a-z0-9-]+(\\.[_a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,4}))", myText))
> emails
[[1]]
[1] "fred@foo.com" "joe@example.com" "twit@here.com"
在这种情况下,
myText
中只有一行,因为我们将所有行粘在了一起,所以返回的
emails
对象中只有一个元素。
请注意,正则表达式字符串并不是一个有效电子邮件地址的严格定义。例如,它仅限于在最后一个点之后介于2到4个字符的地址。因此,它无法匹配
fred@foo.fnord
。还有一些顶级域名的长度超过四个字符,因此您可能需要修改正则表达式。
此外,它仅在名称部分匹配字母数字和点号 - 因此有效的地址,例如
foo+bar@google.com
无法匹配。
解决这两个问题的正则表达式可能是:
"([_+a-z0-9-]+(\\.[_+a-z0-9-]+)*@[a-z0-9-]+(\\.[a-z0-9-]+)*(\\.[a-z]{2,14}))"
但它可能存在其他问题,你最好在网上搜索更好的电子邮件地址正则表达式。我说更好是因为完美的正则表达式并不存在...