You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Haskell使用PCRE库验证邮箱时遇正则解析错误求助

使用pcre-heavy库验证邮箱时的GHC解析错误

问题概述

在GHC 9.12.2版本中,使用pcre-heavy库的模板语法编写邮箱验证正则时,触发解析错误:parse error on input ‘2’,错误定位到正则表达式的{2,64}部分。

相关代码

import ClassyPrelude
import Domain.Validation
import Text.Regex.PCRE.Heavy
import Control.Monad.Except

type Validation e a = a -> Maybe e

validate :: (a -> b) -> [Validation e a] -> a -> Either [e] b
validate constructor validations val = 
  case concatMap (\f -> maybeToList $ f val) validations of
    []    -> Right $ constructor val
    errs  -> Left errs
    
newtype Email = Email { emailRaw :: Text } deriving (Show, Eq, Ord)

rawEmail :: Email -> Text
rawEmail = emailRaw

mkEmail :: Text -> Either [Text] Email
mkEmail =
  validate Email
    [ regexMatches
        [re|^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,64}$|]
        "Not a valid email"
    ]

Cabal配置

default-extensions: TemplateHaskell
                  , ConstraintKinds
                  , FlexibleContexts
                  , NoImplicitPrelude
                  , OverloadedStrings
                  , TemplateHaskell

build-depends:    base ^>=4.21.0.0
                , katip >= 0.8.8.2
                , string-random == 0.1.4.4
                , mtl
                , data-has
                , classy-prelude
                , pcre-heavy
                , time
                , time-lens
                
hs-source-dirs:   src
default-language: GHC2024

错误日志

cabal build
Resolving dependencies...
Build profile: -w ghc-9.12.2 -O1
In order, the following will be built (use -v for more details):
 - practical-web-dev-ghc-0.1.0.0 (lib) (first run)
 - practical-web-dev-ghc-0.1.0.0 (exe:practical-web-dev-ghc) (first run)
Configuring library for practical-web-dev-ghc-0.1.0.0...
Preprocessing library for practical-web-dev-ghc-0.1.0.0...
Building library for practical-web-dev-ghc-0.1.0.0...
[1 of 5] Compiling Domain.Validation ( src/Domain/Validation.hs, dist-newstyle/build/aarch64-osx/ghc-9.12.2/practical-web-dev-ghc-0.1.0.0/build/Domain/Validation.o, dist-newstyle/build/aarch64-osx/ghc-9.12.2/practical-web-dev-ghc-0.1.0.0/build/Domain/Validation.dyn_o )
[2 of 5] Compiling Domain.Auth      ( src/Domain/Auth.hs, dist-newstyle/build/aarch64-osx/ghc-9.12.2/practical-web-dev-ghc-0.1.0.0/build/Domain/Auth.o, dist-newstyle/build/aarch64-osx/ghc-9.12.2/practical-web-dev-ghc-0.1.0.0/build/Domain/Auth.dyn_o )
src/Domain/Auth.hs:42:57: error: [GHC-58481]
    parse error on input ‘2’
   |
42 |         [re|^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,64}$|]
   |                                                         ^

[4 of 5] Compiling Logger           ( src/Logger.hs, dist-newstyle/build/aarch64-osx/ghc-9.12.2/practical-web-dev-ghc-0.1.0.0/build/Logger.o, dist-newstyle/build/aarch64-osx/ghc-9.12.2/practical-web-dev-ghc-0.1.0.0/build/Logger.dyn_o )
[5 of 5] Compiling MyLib            ( src/MyLib.hs, dist-newstyle/build/aarch64-osx/ghc-9.12.2/practical-web-dev-ghc-0.1.0.0/build/MyLib.o, dist-newstyle/build/aarch64-osx/ghc-9.12.2/practical-web-dev-ghc-0.1.0.0/build/MyLib.dyn_o )
Error: [Cabal-7125]
Failed to build practical-web-dev-ghc-0.1.0.0 (which is required by exe:practical-web-dev-ghc from practical-web-dev-ghc-0.1.0.0).

原因分析

pcre-heavy的[re|...]是基于TemplateHaskell的语法糖,它默认将模板中的逗号视为参数分隔符。正则表达式里的{2,64}包含逗号,导致GHC错误地将2解析为模板的第二个输入参数,从而触发语法错误。

解决办法

方法1:转义正则中的逗号

在正则的逗号前添加反斜杠,让TemplateHaskell识别它为正则的一部分而非参数分隔符:

mkEmail :: Text -> Either [Text] Email
mkEmail =
  validate Email
    [ regexMatches
        [re|^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2\,64}$|]
        "Not a valid email"
    ]

方法2:直接使用字符串编译正则

避开模板语法,用pcre-heavy提供的compile函数从字符串编译正则表达式,这样无需处理逗号转义:

mkEmail :: Text -> Either [Text] Email
mkEmail =
  validate Email
    [ regexMatches
        (compile "^[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,64}$")
        "Not a valid email"
    ]

注意:Haskell字符串中的反斜杠需要双重转义,因此正则里的\.要写成\\.。

内容的提问来源于stack exchange,提问作者user51

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 04:13:18