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

时间:2011-05-25 09:46:11

标签: regex 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不理解\S作为转义码。有什么方法可以解决这个问题吗?

在Scala中你可以用3个双引号括起一个字符串,我想知道你是否可以在Haskell中实现类似的东西?

任何帮助都将不胜感激。

3 个答案:

答案 0 :(得分:12)

字符串中的每个反斜杠都必须在双引号内写为双反斜杠。所以

"\\b(((\\S+)?)(@|mailto\\:|(news|(ht|f)tp(s?))\\://)\\S+)\\b"

更一般的说法:你最好不要使用正确的解析器而不是使用正则表达式。正则表达式很少做正确的事情。

答案 1 :(得分:4)

Haskell不支持开箱即用的原始字符串,但是,在GHC中使用quasiquotation实现它们非常容易:

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库。

答案 2 :(得分:1)

我是雷克斯图书馆的忠实粉丝:

http://hackage.haskell.org/package/rex

http://hackage.haskell.org/packages/archive/rex/0.4.2/doc/html/Text-Regex-PCRE-Rex.html

其中不仅使用quasiquoting进行漂亮的正则表达式输入(没有双反斜杠),它还使用类似perl的正则表达式而不是默认烦人的POSIX正则表达式,甚至允许你使用正则表达式作为模式匹配你的方法参数,这是天才。