更新:下面是錯誤的 - 例如 rangeGreedy 2 4 a <* string "aab"
,正則表達式a{2,4}aab
相當於不匹配。提問者的解決方案正確。我不會刪除答案,以防止其他人犯同樣的錯誤。
=========
這不是一個完整的答案,只是寫的貪婪 版本一個可行的辦法。我還沒有找到一個很好的方式來做懶惰的版本。
定義的option
返回Maybes左偏版本:
greedyOption :: ReadP a -> ReadP (Maybe a)
greedyOption p = (Just <$> p) <++ pure Nothing
然後,我們可以做的最多的事情n,其中他們的replicateM
:
upToGreedy :: Int -> ReadP a -> ReadP [a]
upToGreedy n p = catMaybes <$> replicateM n (greedyOption p)
要允許最小計數,分別做強制性部分並附加 它:
rangeGreedy :: Int -> Int -> ReadP a -> ReadP [a]
rangeGreedy lo hi p = (++) <$> count lo p <*> upToGreedy (hi - lo) p
其餘的我的測試代碼,以防萬一它對任何人都有用:
module Main where
import Control.Monad (replicateM)
import Data.Maybe (catMaybes)
import Text.ParserCombinators.ReadP
main :: IO()
main = mapM_ go ["aaaaa", "aaaab", "aaabb", "aabbb", "abbbb", "bbbbb"]
where
go = print . map fst . readP_to_S test
test :: ReadP [String]
test = ((++) <$> rangeGreedy 2 4 a <*> many aOrB) <* eof
where
a = char 'a' *> pure "ay"
aOrB = (char 'a' +++ char 'b') *> pure "ayorbee"