我似乎在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中实现类似的东西?
任何帮助都将不胜感激。
答案 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正则表达式,甚至允许你使用正则表达式作为模式匹配你的方法参数,这是天才。