【问题标题】:Pattern Matching timestamp string模式匹配时间戳字符串
【发布时间】:2018-11-21 03:21:41
【问题描述】:

所以,我有一个 .srt 文件,它是一个格式如下的字幕文件:

1
00:00:01,230 --> 00:00:02,360
This is a subtitle

2
00:00:03,124 --> 00:00:04,400
This is another subtitle

我需要稍微修改一下。我需要做的一件事是检查时间戳的完整性,所以我试图在 haskell 中编写一个函数来检查字符串是否是有效的时间戳

data TimeStamp = TimeStamp Int Int Int Int deriving (Eq, Show, Read)

getTimeStamp :: String -> TimeStamp
getTimeStamp a = read a

isNum :: Maybe Int -> Bool
isNum x = isJust x

isTimeStamp :: String -> Bool
isTimeStamp "" = False
isTimeStamp (hour:':':min:':':sec:',':mil:_) = if (isNum numH) && (isNum numM) && (isNum numS) && (isNum numMil) then True else False
            where numH   = readMaybe [hour] :: Maybe Int
                  numM   = readMaybe [min] ::  Maybe Int
                  numS   = readMaybe [sec] ::  Maybe Int
                  numMil = readMaybe [mil] ::  Maybe Int

问题是,我的模式匹配不起作用。我不太确定我应该如何对子字符串进行模式匹配...有什么帮助吗?

【问题讨论】:

  • 使用 alex+happy,或众多优秀的解析器组合库之一。参见例如this question 讨论了为什么这是基本递归或基本String-processing 函数的优越方法。我很想将此标记为重复,因为我对这两个问题的回答基本相同,仅在被解析的确切语言上有所不同。

标签: haskell


【解决方案1】:

嗯,一般来说,使用解析器组合库确实不会出错。但是,我认为使用简单的手动滚动方法执行此操作没有任何问题,例如,如果您确定时间戳必须遵循非常严格的规范(否则它们将无效)。因此,为了回答您的实际问题,您的代码实际上存在一些问题,尤其是您的模式匹配:

isTimeStamp (hour:':':min:':':sec:',':mil:_)

与您认为的不匹配,因为 minsecmil 匹配 一个 字符。如果您将其更改为:

isTimeStamp (hour:':':min1:min2:':':sec1:sec2:',':mil1:mil2:mil3:_)

你会得到适用于你的时间戳的模式匹配..

您的第二个问题是您的模式匹配并不详尽。您可能想更改 "" 上的匹配并匹配 _ 并更改它们的顺序,因此:

isTimeStamp :: String -> Bool
isTimeStamp (hour:':':min1:min2:':':sec1:sec2:',':mil1:mil2:mil3:"") =   
isTimeStamp _ = False

在此之后,我建议您使用 Maybe monad 进行检查......类似于:

data TimeStamp = TimeStamp Int Int Int Int deriving Show

getTimeStamp :: String -> Maybe TimeStamp
getTimeStamp (hour:':':min1:min2:':':sec1:sec2:',':mil1:mil2:mil3:_) = do
    h   <- readMaybe $ hour:""
    m   <- readMaybe $ min1:min2:""
    s   <- readMaybe $ sec1:sec2:""
    mil <- readMaybe $ mil1:mil2:mil3:""
    return $ TimeStamp h m s mil
isTimeStamp _ = Nothing

但是在这之后你可能会意识到你真正想要的是让TimeStamp成为ReadShow类的实例,所以你可以showit或readit..(或是的..readMaybeit) :-)

【讨论】:

  • 鉴于 OP 的示例数据,我认为我们还需要 hour1:hour2:...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-08
  • 2018-10-04
  • 2016-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多