Parsec how to find “matches” within a string

末鹿安然 提交于 2019-12-01 15:37:57

For an arbitrary parser myParser, it's quite easy:

solution = many (let one = myParser <|> (anyChar >> one) in one)

It might be clearer to write it this way:

solution = many loop
    where 
        loop = myParser <|> (anyChar >> loop)

Essentially, this defines a recursive parser (called loop) that will continue searching for the first thing that can be parsed by myParser. many will simply search exhaustively until failure, ie: EOF.

You can use

 many ( noneOf "0123456789")

i'm not sure about "noneOf" and "digit" types but you can give e try also to

many $ noneOf digit

To find the item in the string, the item is either at the start of the string, or consume one character and look for the item in the now-shorter string. If the item isn't right at the start of the string, you'll need to un-consume the characters used while looking for it, so you'll need a try block.

hasItem = prefixItem <* (many anyChar)
preafixItem = (try item) <|> (anyChar >> prefixItem)
item = <parser for your item here>

This code looks for just one occurrence of item in the string.

(AJFarmar almost has it.)

The replace-megaparsec package allows you to split up a string into sections which match your pattern and sections which don't match by using the sepCap parser combinator.

import Replace.Megaparsec
import Text.Megaparsec
import Text.Megaparsec.Char

let num :: Parsec Void String Int
    num = read <$> many digitChar
>>> parseTest (sepCap num) "I will live to be 111 years <b>old</b> if I work out 4 days a week starting at 22."
[Left "I will live to be "
,Right 111
,Left " years <b>old</b> if I work out "
,Right 4
,Left " days a week starting at "
,Right 22
,Left "."
]
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!