| 赞 | 0 |
| VIP | |
| 好人卡 | |
| 积分 | 3 |
| 经验 | |
| 最后登录 | 2019-10-13 |
| 在线时间 | 953 小时 |
- 梦石
- 0
- 星屑
- 310
- 在线时间
- 953 小时
- 注册时间
- 2007-4-25
- 回帖
- 798
|
发表于 2010-11-14 14:57:19
|
显示全部楼层
http://en.wikipedia.org/wiki/Email_address#Syntax
以上是电子邮箱地址的语法,正式语法定义在 RFC 5321、5322。
其中提到:local-part 的长度上限为 64。
有效的 local-part:
Uppercase and lowercase English letters (a–z, A–Z)
Digits 0 to 9
Characters ! # $ % & ' * + - / = ? ^ _ ` { | } ~
Character . (dot, period, full stop) provided that it is not the first or last character, and provided also that it does not appear two or more times consecutively (e.g. John..Doe@example.com).
Additionally, quoted-strings (e.g., "John Doe"@example.com) are permitted, thus permitting characters otherwise prohibited.
domain 可以是一个有效的主机名,定义:
Hostnames are composed of series of labels concatenated with dots, as are all domain names.
...
Each label must be between 1 and 63 characters long, and the entire hostname (including the delimiting dots) has a maximum of 255 characters.
The Internet standards for protocols mandate that component hostname labels may contain only the ASCII letters 'a' through 'z' (in a case-insensitive manner), the digits '0' through '9', and the hyphen ('-'). The original specification of hostnames in RFC 952, mandated that labels could not start with a digit or with a hyphen, and must not end with a hyphen. However, a subsequent specification (RFC 1123) permitted hostname labels to start with digits.
这里我们以 RFC 1123 定义的主机名为标准。
domain 同时也可以是 IP 地址:
In addition, the domain part may be an IP address literal, surrounded by square braces ...
IPv4 地址语法由 RFC 1918 定义,简单地说即是以句号分隔的四个 8 位无符号整数。
同时,根据 IP 标准,电子邮箱地址整体长度不得超过 254。
尝试写了一下:- #coding: GBK
- # local-part@domain
- local_char = '(?:[a-zA-Z0-9!#\$\%&\'*/=?^_`{|}~-])'
- domain_label = '(?:[a-zA-Z0-9]+(?:-+[a-zA-Z0-9]+)*)'
- zero_to_255 = '(?:\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])'
- $pattern = %r<
- # local-part
- (?:(?:#{local_char}+(?:\.#{local_char}+)*)|".*")
- @
- # domain
- (?:#{domain_label}(?:\.#{domain_label})*|\[#{zero_to_255}(?:\.#{zero_to_255}){3,3}\])
- >x
- def assert_match(str, expected)
- if !(expected ^ (str[$pattern] != str))
- puts "预期#{expected ? '要' : '不'}匹配:"
- puts str
- puts "结果#{expected ? '不' : '却'}匹配。"
- exit(1)
- end
- end
- assert_match('user@example.com', true)
- assert_match("66rpg.USER@66rpg.com", true)
- assert_match("death.king@test.com", true)
- assert_match(".deathking@test.com", false)
- assert_match("deathking.@test.com", false)
- assert_match('china.66rpg.forums.moderators.zh99998@66rpg.com.cn', true)
- assert_match('1993de?at!hk#i$n%g@localhost', true)
- assert_match('death>ki/ng@localhost', false)
- assert_match('e@t.c',true)
- assert_match('e@t.c.', false)
- assert_match('DEATHKING@66RPG.COM', true)
- assert_match('"雷欧纳德 sama 的邮箱哦>_<"@66rpg.net', true)
- assert_match('"!@#$%^&*"特殊字符君的邮箱哦%^&*<>:{"}"@example.org', true)
- assert_match('deathking@[127.0.0.1]', true)
- assert_match('deathking@192.168.0.1', true) # 这是主机名
- assert_match('deathking@32768.1348.1083.19735', true) # 这也是主机名
- assert_match('deathking@[192.168.0,1]', false)
- assert_match('deathking@[8.0.8.256]', false)
- assert_match('deathking@[8.300.8.255]', false)
- assert_match('deathking@[8.30.260.255]', false)
- assert_match('deathking@[8.0.8.255]', true)
- assert_match('deathking@[-3.3.5.7]', false)
- assert_match('deathking@[192.168.178.123.]', false)
- puts '测试全部通过。'
- string = '大家好,我的名字叫Deathking,我的Email:是deathking03323@66rpg.cn哦,常联系!'
- puts string[$pattern]
复制代码 大概是这样。细微处还可以稍作调整,比如那些特殊字符,虽然标准允许,但大多数电子邮件客户端都不会允许。还可以加上 IPv6 的匹配。
长度上限在表达式中没有处理,因为据我所知,两级以上的动态长度的字元,同时又有长度限制的语言并非正则语言,所以正则表达式无法做到。静态长度的字元自然可以限制长度,如:
(?:.){1,63}
接受长度上限为 63 的字符串。但如果圆括号中的字元长度也是动态的,那正则表达式就无法描述了。 |
评分
-
查看全部评分
|