簡體   English   中英

如何使用Parsec解析僅在一定范圍內的整數字符串?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM