首页 文章

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

提问于
浏览
5

我似乎在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 回答

  • 4

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

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

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

  • 1

    Haskell使用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库 .

  • 12

    我是Rex库的忠实粉丝:

    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正则表达式,甚至允许您使用正则表达式作为模式匹配您的方法参数,这是天才 .

相关问题