Haskell 解析电子邮件地址的函数

Haskell function that parses an email address

是否有 Haskell 函数以标准格式解析电子邮件地址?例如:

parseEmailAddress "Jon Doe<jon.doe@mail.com>"

会 return 是这样的:

Address (Just "Jon Doe") "jon.doe@mail.com"

我在 mime-mail 包中找不到执行此操作的函数。

像这样的东西行得通吗:

parseEmailAddress xs =
  case break (== '<') of
    (mail, "") -> Address Nothing mail
    (name, mail) -> Address (Just name) (init (tail mail))

这假定名称不包含 < 字符。

好的。这是我写的。

{-# LANGUAGE NamedFieldPuns #-}

module Email (parseEmailAddress) where

import           Text.Parsec (parse)
import           Text.Parsec.Rfc2822 (NameAddr(..), name_addr)
import           Network.Mail.Mime (Address(..))
import           Data.Text (pack)
import           Data.List (elem)

mapMaybe :: (a -> b) -> Maybe a -> Maybe b
mapMaybe _ Nothing = Nothing
mapMaybe f (Just a) = Just (f a)

-- | Given a string email address, spits out an Address record
parseEmailAddress :: String -> Maybe Address
parseEmailAddress str =
  case parse name_addr "" addr of
    Left _ ->
      Nothing
    Right (NameAddr { nameAddr_name, nameAddr_addr }) ->
      Just (Address (mapMaybe pack nameAddr_name) (pack nameAddr_addr))
  where
    -- Standardize the email address
    addr = if '<' `elem` str then str else "<" ++ str ++ ">"

那么,该函数将按如下方式工作:

parseEmailAddress "johndoe@example.com"  -- Just (Address Nothing "johndoe@example.com")

parseEmailAddress "John Doe <john.doe@example.com>" -- Just (Address (Just "John Doe") "johndoe@example.com")

parseEmailAddress "johndoe" -- Nothing