百度下郵箱格式的正則表示,可以搜索到各式各樣,五花八門的表示。若是沒有仔細甄別,錯誤使用其中的一些代碼,則極可能形成在遇到一些特殊的郵箱格式時沒法識別。這裏就分析下郵件相關的RFC標準,可詳見RFC 5322, Internet Message Format或[2-RFC5322], 但在此以前須要先學習下[1-RFC5234]中關於ABNF的核心規則。正則表達式
[1-RFC5234] 中Appendix B. Core ABNF of ABNFshell
B.1. Core Rulesdom
ALPHA = %x41-5A / %x61-7A ; A-Z / a-z BIT = "0" / "1" CHAR = %x01-7F ; any 7-bit US-ASCII character, excluding NUL CR = %x0D ; carriage return CRLF = CR LF ; Internet standard newline CTL = %x00-1F / %x7F ; controls DIGIT = %x30-39 ; 0-9 DQUOTE = %x22 ; " (Double Quote) HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" HTAB = %x09 ; horizontal tab LF = %x0A ; linefeed LWSP = *(WSP / CRLF WSP) ; Use of this linear-white-space rule ; permits lines containing only white ; space that are no longer legal in ; mail headers and have caused ; interoperability problems in other ; contexts. ; Do not use when defining mail ; headers and use with caution in ; other contexts. OCTET = %x00-FF ; 8 bits of data SP = %x20 ; space VCHAR = %x21-7E ; visible (printing) characters WSP = SP / HTAB ; white space
如下內容見[2-RFC5322], 章節編號與原文保持一致。 學習
2 Message詞法分析(Lexical Analysis of Messages)
this
取值範圍在1-127的字符被稱爲US-ASCII字符.atom
Messages可分爲許多行字符,一行是用兩個相連的字符carriage-return(CR: ASCII碼值13)與line-feed(LF: ASCII碼值10)分隔, 一般寫做CRLF.spa
Message是由header字段, 可選的body字段組成。code
header section是由一些特定語法的許多行組成, header section後面是一個空行,接下來是body字段。orm
本規範中使用header field描述單個字段,用header section描述全部header字段。token
每一行字符數務必(MUST)不能超過998個,不包括CRLF之外一般不該當超過78個字符。
998加上CRLF達到1000個字符,有許多接收方實現限定一行不能超過1000個字符。
78加上CRLF達到80個字符,有許多顯示界面一行超過80個字符後被截斷或顯示到下一行。
Header Fields先是一個field name, 接下來是一個冒號, 接下來是一個field body, 後面是CLRF.
field name必須是可打印US-ASCII字符組成,即值爲[33,126]之間除冒號之外的字符。
field body必須是可打印US-ASCII字符, 空格(SP:ASCII碼值32), horizontal tab(HTAB:
ASCII碼值9)字符組成。SP與HTAB組合即爲WSP(white space characters).
field body務必不能(MUST NOT)包含CRLF, 除了用於"folding"與"unfolding"之外。
一些field body被稱爲"unstructured", 表示無需進一步處理的單行字符。
一些field body被稱爲"structured", 由一些特殊token組成, 這些token後面能夠有comments與空格字符.
每一個header field一般是由一行字符,由field name, 冒號和field body組成。
考慮到須要處理每行有998/78字符, header field中的field body部分可用多行來表示,這被稱爲"folding".
例以下面header field:
Subject: This is a test
能夠被表示爲
Subject: This
is a test
從folded多行變爲單行的過程被稱爲"unfolding", 即去掉CRLF並當即跟一個WSP.
每一個header field應當用其unfolded格式來作進一步的語法與此法分析。
unfolded header field沒有長度限制。
3. 語法(Syntax)
3.2 詞法(Lexical)tokens
3.2.1. Quoted characters
quoted-pair = ("\" (VCHAR / WSP)) / obs-qp
3.2.2. Folding White Space and Comments
header字段bodies中, 許多elements之間能夠存在空白字符(White space characters), 這裏的字符包含用於folding的空格;
圓括號(parentheses)中的字符串被視爲comments。
下面定義了folding white space (FWS)和comment結構。
圓括號(parentheses)中的字符串只要不是在引號串內就被視爲comments, Comments能夠嵌套(nest).
有一些地方可隨意插入comments與FWS, 爲此新定義一個"CFWS" token.
可是,在一個folded header字段的任意一行,不能都是由WSP字符組成。
FWS = ([*WSP CRLF] 1*WSP) / obs-FWS ; Folding white space ctext = %d33-39 / ; 可打印US-ASCII字符, %d42-91 / ; 取值在[33-126]範圍內但不包含 %d93-126 / ; 40="(", 41=")", or 92="\" obs-ctext %d33-39: 33: "!" 34: """ 35: "#" 36: "$" 37: "%" 38: "&" 39: "'" 42 "*" 43 "+" 44 "、" 45 "-" 46 "." 47 "/" 48-57: "0"-"9" 58: ":" 59: ";" 60: "<" 61: "=" 62: ">" 63: "?" 64: "@" 65-90: "A-Z" 91: "[" 93: "]" 94: "^" 95: "-" 96: "'" 97-122: "a-z" 123: "{" 124: "|" 125: "}" 126: "~" ccontent = ctext / quoted-pair / comment comment = "(" *([FWS] ccontent) [FWS] ")" CFWS = (1*([FWS] comment) [FWS]) / FWS
3.2.3. Atom
在structured header field bodies中有一些productions是由一些基本字符組成的簡單串,
這些productions被稱爲atoms.
但有一些productions容許句點字符(".", ASCII值爲46), 所以引入"dot-atom" token來表示這種狀況。
atext = ALPHA / DIGIT / ; 不包含specials的可打印US-ASCII字符 "!" / "#" / ; 用於atoms. "$" / "%" / "&" / "'" / "*" / "+" / "-" / "/" / "=" / "?" / "^" / "_" / "`" / "{" / "|" / "}" / "~" atom = [CFWS] 1*atext [CFWS] dot-atom-text = 1*atext *("." 1*atext) dot-atom = [CFWS] dot-atom-text [CFWS] specials = "(" / ")" / ; atext中未出現的特殊字符 "<" / ">" / "[" / "]" / ":" / ";" / "@" / "\" / "," / "." / DQUOTE
3.2.4. Quoted Strings
用雙引號(DQUOTE, ASCII值34)包含的串.
qtext = %d33 / ; 不包含雙引號"""與反斜槓"\"的可打印字符。 %d35-91 / %d93-126 / obs-qtext qcontent = qtext / quoted-pair quoted-string = [CFWS] DQUOTE *([FWS] qcontent) [FWS] DQUOTE [CFWS]
用雙引號包含的串被稱爲一個unit, 即雙引號串在語法上與atom一致。
由於雙引號串可包含FWS, 即容許folding.
並且注意雙引號串中能夠有雙引號串, 引發能夠有雙引號字符與反斜槓(backslash)字符。
從語法上講, 雙引號串中的"\"與FWS/CFWS中的CRLF都是不可見的,所以它們不是雙引號串的一部分。
3.2.5. 其餘Tokens
定義三個token: word與phrase用於atoms和/或雙引號串的組合, unstructured 用於
unstructured header字段, 以及structured header字段中的一些地方.
word = atom / quoted-string phrase = 1*word / obs-phrase unstructured = (*([FWS] VCHAR) *WSP) / obs-unstruct
3.3. Date與Time規範
date-time = [ day-of-week "," ] date time [CFWS] day-of-week = ([FWS] day-name) / obs-day-of-week day-name = "Mon" / "Tue" / "Wed" / "Thu" / "Fri" / "Sat" / "Sun" date = day month year ; 應當表示本地時間 day = ([FWS] 1*2DIGIT FWS) / obs-day ; 一個月的第幾天 month = "Jan" / "Feb" / "Mar" / "Apr" / "May" / "Jun" / "Jul" / "Aug" / "Sep" / "Oct" / "Nov" / "Dec" year = (FWS 4*DIGIT FWS) / obs-year ; 四位數字 time = time-of-day zone time-of-day = hour ":" minute [ ":" second ] ; 應當表示本地時間, 一天中的時:分[:秒], ; 範圍00:00:00 - 23:59:60 hour = 2DIGIT / obs-hour minute = 2DIGIT / obs-minute second = 2DIGIT / obs-second zone = (FWS ( "+" / "-" ) 4DIGIT) / obs-zone ; date與time-of-day偏離UTC或GMT的誤差\ ; +表示ahead of(即east of)UTC, -表示behind(即west of) UTC ; 前兩個數字表示hours誤差, 後兩個數字表示minutes誤差 ; +hhmm表示 +(hh * 60 + mm) 分鐘, -hhmm表示 -(hh * 60 + mm) 分鐘 ; "+0000"用於表示UTC的時區 ; "-0000"用於表示本地時區生成的時間, date-time不包含本地時區的信息
3.4. Address規範
Addresses表示messages的接收與發送方.
一個address能夠是單個郵箱,也能夠是一組郵箱。
address = mailbox / group mailbox = name-addr / addr-spec name-addr = [display-name] angle-addr angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr group = display-name ":" [group-list] ";" [CFWS] display-name = phrase mailbox-list = (mailbox *("," mailbox)) / obs-mbox-list address-list = (address *("," address)) / obs-addr-list group-list = mailbox-list / CFWS / obs-group-list
一個mailbox一般由兩部分組成:(1) 一個可選的display-name, (2) 用<>封裝的addr-spec地址。
mailbox的一歲簡化形式是隻有addr-spec地址,沒有接收方名稱, 也沒有<>。
3.4.1. Addr-Spec規範
addr-spec = local-part "@" domain local-part = dot-atom / quoted-string / obs-local-part domain = dot-atom / domain-literal / obs-domain domain-literal = [CFWS] "[" *([FWS] dtext) [FWS] "]" [CFWS] dtext = %d33-90 / ; 可打印US-ASCII字符, %d94-126 / ; 不包含 "[", "]", or "\" obs-dtext
3.5. Overall Message Syntax
message由header fields, 接下來是一個可選的message body.
message中的一行最大998個字符,推薦最大爲78個字符, 這裏都不包含CRLF.
在message body中, 雖然在text rule中列出的全部字符均可以用, 但不鼓勵使用US-ASCII控制字符(值1到8, 11, 12, 14-31),
由於沒法保證接收方如何來顯示它們。
message = (fields / obs-fields) [CRLF body] body = (*(*998text CRLF) *998text) / obs-body text = %d1-9 / ; Characters excluding CR %d11 / ; and LF %d12 / %d14-127
其餘略。。。
郵箱地址格式主要參見上面的3.4.1. Addr-Spec規範, 建議參照這裏的規範來編寫正則表達式,若是本身沒有能力編寫正則表達式則建議直接採用PHP、JAVA、C#、C++、C等語言中現成的庫來判斷。
參考資料:
[1-RFC5234] RFC 5234, Augmented BNF for Syntax Specifications: ABNF, Standards Track, January 2008, http://www.rfc-editor.org/rfc/rfc5234.txt
[2-RFC5322] RFC 5322, Internet Message Format, Standards Track, October 2008, http://www.rfc-editor.org/rfc/rfc5322.txt