Haskell中对字符串列表所有元素执行操作的实现求助
Haskell提取字符串列表中的工作时长数值
基础字符串操作实现
无需额外依赖,用Haskell标准库函数即可完成。核心逻辑是定位括号位置,截取目标子串后转换为Double类型:
import Data.List (break) import Text.Read (readMaybe) -- 可选,用于处理格式错误的安全转换 -- 基础版(假设所有字符串格式完全符合要求) extractHours :: String -> Double extractHours s = read $ takeWhile (/= ')') $ tail $ snd $ break (== '(') s -- 安全版(兼容格式错误场景,返回Maybe Double) extractHoursSafe :: String -> Maybe Double extractHoursSafe s = case break (== '(') s of (_, '(':rest) -> readMaybe $ takeWhile (/= ')') rest _ -> Nothing -- 测试用例 timeStrings :: [String] timeStrings = [ "Working time: 9-17 (8h)", "Working time: 9-16 (7h)", "Working time: 10-17 (7h)", "Working time: 8-17:30 (9.5h)" ] -- 生成结果列表 hourList :: [Double] hourList = map extractHours timeStrings -- 安全版结果列表 hourListSafe :: [Maybe Double] hourListSafe = map extractHoursSafe timeStrings
正则表达式实现
如果需要适配更多格式变种,可使用text-regex-tdfa库实现灵活匹配:
- 先通过Cabal安装依赖:
cabal install text-regex-tdfa
- 实现代码:
import Text.Regex.TDFA ((=~)) extractHoursRegex :: String -> Double extractHoursRegex s = read $ head (s =~ "\\((\\d+\\.?\\d*)h\\)" :: [[String]]) !! 1 hourListRegex :: [Double] hourListRegex = map extractHoursRegex timeStrings
正则表达式\((\d+\.?\d*)h\)的含义:
\(:匹配左括号(\d+\.?\d*):捕获整数或小数格式的数值h\):匹配"h)"结尾的固定格式
代码说明
break (== '('):将字符串拆分为左括号前的内容和从左括号开始的部分takeWhile (/= ')'):截取到右括号前的子串,得到纯数字字符串read/readMaybe:将数字字符串转换为Double类型(readMaybe在格式错误时返回Nothing,避免程序崩溃)map:将提取逻辑批量应用到列表的每个元素,生成最终的Double列表
内容的提问来源于stack exchange,提问作者MechWright
相关产品推荐
相关产品推荐

