模式匹配时间戳字符串



所以,我有一个.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

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

一般来说,使用解析器组合子库是不会出错的。然而,我不认为用简单的手动滚动方法做这件事有什么错,例如,如果你确信时间戳必须遵循非常严格的规范(否则它们将无效(。因此,为了回答您的实际问题,您的代码实际上有一些错误,但特别是您的模式匹配:

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

之后,我建议您使用Maybemonad进行检查。。类似于:

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(:-(

最新更新