Haskell中用于正则表达式的“原始”字符串

问题描述

| 我似乎在Haskell中创建正则表达式时遇到问题,我想做的就是转换此字符串(与文本中的URL匹配)
\\b(((\\S+)?)(@|mailto\\:|(news|(ht|f)tp(s?))\\://)\\S+)\\b
变成正则表达式,麻烦的是我一直在ghci中收到此错误
Prelude Text.RegExp> let a = fromString \"\\b(((\\S+)?)(@|mailto\\:|(news|(ht|f)tp(s?))\\://)\\S+)\\b\"

<interactive>:1:27:
    lexical error in string/character literal at character \'S\'
我猜这是失败的,因为Haskell不将ѭ2理解为转义码。有什么办法可以解决这个问题? 在Scala中,您可以用3个双引号引起来的字符串,我想知道您是否可以在Haskell中实现类似的功能? 任何帮助,将不胜感激。     

解决方法

字符串中的每个反斜杠都必须在双引号内写为双反斜杠。所以
\"\\\\b(((\\\\S+)?)(@|mailto\\\\:|(news|(ht|f)tp(s?))\\\\://)\\\\S+)\\\\b\"
更为笼统的说法是:最好编写一个正确的解析器,而不要使用正则表达式。正则表达式很少会做正确的事情。     ,Haskell不支持开箱即用的原始字符串,但是,在GHC中,使用准引用很容易实现它们:
r :: QuasiQuoter
r = QuasiQuoter {      
    quoteExp  = return . LitE . StringL
    ...
}
用法:
ghci> :set -XQuasiQuotes
ghci> let s = [r|\\b(((\\S+)?)(@|mailto\\:|(news|(ht|f)tp(s?))\\://)\\S+)\\b|]
ghci> s
\"\\\\b(((\\\\S+)?)(@|mailto\\\\:|(news|(ht|f)tp(s?))\\\\://)\\\\S+)\\\\b\"
我已经发布了此代码的稍微扩展和记录的版本,作为Hackage上的
raw-strings-qq
库。     ,我是Rex库的忠实拥护者: http://hackage.haskell.org/package/rex http://hackage.haskell.org/packages/archive/rex/0.4.2/doc/html/Text-Regex-PCRE-Rex.html 它不仅使用准引号输入漂亮的正则表达式(没有双反斜杠),还使用类似perl的正则表达式,而不使用默认的烦人的POSIX正则表达式,甚至允许您使用正则表达式作为与您的方法参数匹配的模式,这真是天才。