正则表达式是解析SMTP接收行的一个很好的选择

时间:2012-04-28 23:02:12

标签: java regex smtp

我想解析RFC822 (SMTP)“已接收”行的元素,这些行在规范中正式定义,例如:

atom        =  1*

[...]

received    =  "Received"    ":"            ; one per relay
                       ["from" domain]           ; sending host
                       ["by"   domain]           ; receiving host
                       ["via"  atom]             ; physical path
                      *("with" atom)             ; link/mail protocol
                       ["id"   msg-id]           ; receiver msg id
                       ["for"  addr-spec]        ; initial form
                       ";"    date-time         ; time received

[...]

msg-id      =  ""            ; Unique message id

[...]

addr-spec   =  local-part "@" domain        ; global address

etc. for domain, date-time, etc.

这是一个真实的例子:

Received: from ll-194.132.162.89.kv.sovam.net.ua (ll-194.132.162.89.kv.sovam.net.ua [83.170.243.194] (may be forged)) by raq2073.uk2.net (8.10.2/8.10.2) with ESMTP id lASHDDE10765 for <johnsmithsvt@matts.co.uk>; Wed, 28 Nov 2007 17:13:13 GMT

正则表达式是一个很好的策略来捕获接收到的线路的部分?

我意识到许多SMTP服务器没有正确格式化接收到的行(在现实生活中)。

否则,有没有人知道Java中的这个库做得好呢?

编辑这是一个显示正则表达式的fiddle和我已经打了一段时间的测试,这似乎有效。

Received:\s+(?:from\s+(.+?))?(?:\(qmail (.+?)\))?(?:\s+by\s+(.+?))?(?:\\s+via\s+(.+?))?(?:\s+with\s+(.+?))?(?:\;?\s+id\s+(.+?))?(?:\s+for\s+(.+?))?(?:;\s*(?!.*\;.*)(.+))?$

1 个答案:

答案 0 :(得分:1)

选择实际上取决于你想要达到的目标。

为了捕获接收器行的特定部分(例如“给我来自部分”),正则表达式很棒。

如果你需要一个完整的语法解析器,那么单独使用正则表达式是不够的。特别是addr-spec有很多特殊情况,正则表达式无法正确处理每一个(explanation)。正则表达式不是解析器。

上次我需要一个实际的解析器,我使用JavaCC编写了自己的解析器。如果你对语法和解析有所了解,我只会建议你走这条路。