Attoparsec:跳过(但不包括)多字符定界符

Attoparsec: skipping up to (but not including) a multi-char delimiter

我有一个几乎可以包含任何字符的字符串。字符串内部有分隔符 {{{

例如:afskjdfakjsdfkjas{{{fasdf.

使用 attoparsec,编写跳过 {{{ 之前的所有字符但不消耗 {{{Parser () 的惯用方法是什么?

你可以像这样稍微难一点:

foo = many $ do
  Just c <- fmap (const Nothing) (try $ string "{{{") <|> fmap Just anyChar
  return c

或者您可以像这样使用此辅助函数 manyTill

foo = manyTill anyChar (try $ string "{{{")

使用 attoparseclookAhead(应用解析器而不消耗任何输入)和 manyTill 编写一个解析器,消耗所有内容直到(但不包括){{{ 分隔符。然后您可以自由地应用该解析器并丢弃其结果。

{-# LANGUAGE OverloadedStrings #-}

import Control.Applicative ( (<|>) )
import Data.Text ( Text )
import qualified Data.Text as T
import Data.Attoparsec.Text
import Data.Attoparsec.Combinator ( lookAhead, manyTill )

myParser :: Parser Text
myParser = T.concat <$> manyTill (nonOpBraceSpan <|> opBraceSpan)
                                 (lookAhead $ string "{{{")
                    <?> "{{{"
  where
    opBraceSpan    = takeWhile1 (== '{')
    nonOpBraceSpan = takeWhile1 (/= '{')

在 GHCi 中:

λ> :set -XOverloadedStrings 
λ> parseTest myParser "{foo{{bar{{{baz"
Done "{{{baz" "{foo{{bar"