[英]How to parse a string of integers only in some range with Parsec?
我正在嘗試通過解析格式為“ YYYYMMDD”的日期字符串(例如“ 20161030”)來學習Parsec。 我的解決方案是:
date :: Parser (String, String, String)
date = do
year <- replicateM 4 digit
month <- replicateM 2 digit
day <- replicateM 2 digit
return (year, month, day)
但是問題是“ 20161356”也是我的代碼的有效日期。
如何驗證“ MM”在1到12之間? 並且“ DD”在1到31之間?
您可以按照Thomas M.DuBuisson的建議增加一名guard
:
date :: Parser (String, String, String)
date = do
year <- replicateM 4 digit
month <- replicateM 2 digit
day <- replicateM 2 digit
guard $ read month > 0 && read month <= 12 && read day > 0 && read day <= 31
return (year, month, day)
但是,這會導致錯誤的錯誤消息:
λ> parse date "" "20161356"
Left (line 1, column 9):unknown parse error
我們可以通過結合使用guard
和<?>
來解決此問題,以提供更好的錯誤消息:
date :: Parser (String, String, String)
date = do
year <- replicateM 4 digit
month <- replicateM 2 digit
guard (read month > 0 && read month <= 12) <?> "valid month (1–12)"
day <- replicateM 2 digit
guard (read day > 0 && read day <= 31) <?> "valid day (1–31)"
return (year, month, day)
使用這種方法,您會收到一條更有用的錯誤消息:
λ> parse date "" "20161356"
Left (line 1, column 7):
expecting valid month (1–12)
作為一個方面說明,我認為這是有價值的驗證(或至少完整性檢查)的日期分析器,它可確保日期驗證與您的解析器和錯誤處理代碼的其余部分組成。 您不會忘記稍后在代碼中檢查日期,並且錯誤已正確本地化,如果您要分析包含大量日期的文檔,這將非常有用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.