Parsec如何在字符串中找到"匹配"

Sea*_*ess 10 haskell parsec

如何使用parsec解析字符串中所有匹配的输入并丢弃其余的?

示例:我有一个简单的数字解析器,如果我知道它们之间的区别,我可以找到所有数字:

num :: Parser Int
num = read <$> many digit

parse (num `sepBy` space) "" "111 4 22"
Run Code Online (Sandbox Code Playgroud)

但如果我不知道数字之间是什么呢?

"I will live to be 111 years <b>old</b> if I work out 4 days a week starting at 22."
Run Code Online (Sandbox Code Playgroud)

many anyChar 不作为分隔符,因为它消耗一切.

那么我怎样才能得到与我想忽略的东西包围的任意解析器相匹配的东西?


编辑:请注意,在真正的问题中,我的解析器更复杂:

optionTag :: Parser Fragment
optionTag = do
    string "<option"
    manyTill anyChar (string "value=")
    n <- many1 digit
    manyTill anyChar (char '>')
    chapterPrefix
    text <- many1 (noneOf "<>")
    return $ Option (read n) text
  where
    chapterPrefix = many digit >> char '.' >> many space
Run Code Online (Sandbox Code Playgroud)

AJF*_*mar 8

对于任意解析器myParser,它非常简单:

solution = many (let one = myParser <|> (anyChar >> one) in one)
Run Code Online (Sandbox Code Playgroud)

用这种方式写它可能更清楚:

solution = many loop
    where 
        loop = myParser <|> (anyChar >> loop)
Run Code Online (Sandbox Code Playgroud)

本质上,这定义了一个递归解析器(被称为loop),它将继续搜索可以解析的第一个东西myParser.many将简单地搜索到彻底失败,即:EOF.