模式匹配时间戳字符串

时间:2018-11-20 17:46:36

标签: haskell

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

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

1 个答案:

答案 0 :(得分:3)

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

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

但是之后,您可能会意识到自己真正想要的是将TimeStampRead类的实例设为Show,因此可以show it或{。{1}} ..(或是。read它:-)