email.utils.parseaddr() 解析姓名和邮箱地址
本文最后更新于2 天前,其中的信息可能已经过时,如有错误请发送邮件到184874483@qq.com

题目考点

这道题主要考:

  1. email.utils.parseaddr() 解析姓名和邮箱地址
  2. 正则表达式 re 判断字符串格式
  3. 循环读取多行输入
  4. 按条件筛选并输出原格式数据

这道题不是让你手动切字符串,而是希望你用 email.utils 把:

DEXTER <dexter@hotmail.com>

解析成:

('DEXTER', 'dexter@hotmail.com')

然后只检查后面的邮箱地址是否合法。


审题

题目给你 n 行,每一行格式大致是:

name <username@domain.extension>

要求你只打印邮箱合法的那几行,并且输出顺序要和输入顺序一致。

合法邮箱要满足:

username@domain.extension

其中:

部分要求
username第一个字符必须是英文字母
username 后续字符可以是字母、数字、_-.
domain只能是英文字母
extension只能是英文字母,长度为 1 到 3

样例中:

DEXTER <dexter@hotmail.com>

是合法的。

而:

VIRUS <virus!@variable.:p>

不合法,因为 virus! 里面有 !,并且扩展名 :p 也不符合要求。


思路提示

先不要急着写正则。你可以按下面三步想:

第一步,先用 email.utils.parseaddr() 把一整行拆开。

例如:

DEXTER <dexter@hotmail.com>

可以拆成:

name = "DEXTER"
address = "dexter@hotmail.com"

第二步,只判断 address 这一部分是否合法。

也就是说,我们要判断:

dexter@hotmail.com

是不是满足:

用户名@域名.扩展名

第三步,如果合法,就用 email.utils.formataddr() 再拼回标准格式并输出。


完整设计思路

第一步:读取输入行数

题目第一行是整数 n,表示后面有多少组姓名和邮箱。

n = int(input())

第二步:逐行读取姓名和邮箱

用循环读取 n 行:

for _ in range(n):
    line = input()

这里 _ 表示这个循环变量本身不重要,只是重复执行 n 次。

第三步:解析姓名和邮箱

用:

name, address = email.utils.parseaddr(line)

例如:

DEXTER <dexter@hotmail.com>

会得到:

name = "DEXTER"
address = "dexter@hotmail.com"

第四步:用正则判断邮箱地址

核心正则可以写成:

r'[A-Za-z][A-Za-z0-9_.-]*@[A-Za-z]+\.[A-Za-z]{1,3}'

拆开看:

正则片段含义
[A-Za-z]用户名第一个字符必须是英文字母
[A-Za-z0-9_.-]*后续字符可以是字母、数字、下划线、点、横线,出现 0 次或多次
@必须有一个 @
[A-Za-z]+域名只能由英文字母组成,至少 1 个
\.必须有一个真正的点号 .
[A-Za-z]{1,3}扩展名只能是英文字母,长度 1 到 3

注意这里的:

\. 

表示真正的点号。

如果直接写:

.

在正则里它表示“任意一个字符”,不是普通点号。


代码实现

import re
import email.utils

n = int(input())

pattern = r'[A-Za-z][A-Za-z0-9_.-]*@[A-Za-z]+\.[A-Za-z]{1,3}'

for _ in range(n):
    line = input()

    name, address = email.utils.parseaddr(line)

    if re.fullmatch(pattern, address):
        print(email.utils.formataddr((name, address)))

这里推荐用:

re.fullmatch(pattern, address)

它表示整个 address 必须完整匹配这个正则规则。

如果只用 re.match(),它默认是从开头开始匹配,但不一定要求整个字符串都匹配完。初学阶段用 fullmatch() 更直观。


运行演示

输入:

2
DEXTER <dexter@hotmail.com>
VIRUS <virus!@variable.:p>

程序先读到:

n = 2

第一行:

DEXTER <dexter@hotmail.com>

经过:

email.utils.parseaddr(line)

得到:

name = "DEXTER"
address = "dexter@hotmail.com"

然后判断:

dexter@hotmail.com

拆开看:

dexter   -> 用户名,d 开头是字母,后面都是合法字符
hotmail  -> 域名,全是字母
com      -> 扩展名,全是字母,长度是 3

所以合法,输出:

DEXTER <dexter@hotmail.com>

第二行:

VIRUS <virus!@variable.:p>

解析后:

name = "VIRUS"
address = "virus!@variable.:p"

判断邮箱:

virus!   -> 用户名里面有 !,不合法
:p       -> 扩展名也不合法

所以这一行不输出。

最终输出:

DEXTER <dexter@hotmail.com>

方法总结

这类题的核心不是一上来写代码,而是先拆格式。

以后遇到“判断字符串是否合法”的题,可以按这个顺序思考:

第一步,先明确字符串整体格式。
比如这题是:

username@domain.extension

第二步,把格式拆成几段。
比如:

username
@
domain
.
extension

第三步,分别给每一段写规则。
比如:

username 第一个字符必须是字母
domain 只能是字母
extension 长度 1 到 3

第四步,把这些规则拼成一个完整正则。

这道题的关键正则是:

r'[A-Za-z][A-Za-z0-9_.-]*@[A-Za-z]+\.[A-Za-z]{1,3}'

你不需要一口气背下来,而是要学会从题目条件一步一步拼出来。


练习

请判断下面哪些邮箱地址合法:

ALEX <alex-99@gmail.com>
BOB <1bob@yahoo.com>
CAT <cat.name@abc.cn>
DOG <dog@hello.python>
EVA <eva_2024@school.edu>

提示:

重点检查三件事:

  1. 用户名第一个字符是不是英文字母
  2. domain 是不是只包含英文字母
  3. extension 长度是不是 1 到 3,并且只包含英文字母
文末附加内容
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇