[英]How can I use this regex in Haskell?
我正在尝试制作一个简单的Haskell程序,该程序将采用类似于someFilenameHere0035.xml
任何行并返回0035
。 我的样本输入文件input.txt如下所示:
someFilenameHere0035.xml
anotherFilenameHere4465.xml
并运行: cat input.txt | runhaskell getID.hs
cat input.txt | runhaskell getID.hs
应该返回:
0035
4465
我很难解决这个问题。 这是我到目前为止的内容:
import Text.Regex.PCRE
getID :: String -> [String]
getID str = str =~ "([0-9]+)\\.xml" :: [String]
main :: IO ()
main = interact $ unlines . getID
但是我收到一条我根本听不懂的错误消息:
• No instance for (RegexContext Regex String [String])
arising from a use of ‘=~’
• In the expression: str =~ "([0-9]+)\\.xml" :: [String]
In an equation for ‘getID’:
getID str = str =~ "([0-9]+)\\.xml" :: [String] (haskell-stack-ghc)
我感觉我真的很近,但是我不知道从这里去哪里。 我究竟做错了什么?
首先,您只需要数字部分,因此我们可以摆脱\\\\.xml
。
regex-pcre库为RegexContext Regex String String
定义了一个实例,但没有为RegexContext Regex String [String]
定义了一个实例,因此出错。
因此,如果我们将类型签名更改为String -> String
则可以解决该错误。
unlines
期望使用[String],因此为了测试此时的性能,我编写了一个快速函数,将其参数包装在列表中(可能有更好的方法,但这不是问题的重点):
toList :: a -> [a]
toList a = [a]
使用main = interact $ unlines . toList . getID
运行命令main = interact $ unlines . toList . getID
main = interact $ unlines . toList . getID
main = interact $ unlines . toList . getID
输出0035,所以我们main = interact $ unlines . toList . getID
。
getID
传递了文件内容的字符串,这些内容方便地用\\n
字符分隔。 因此,我们可以使用splitOn "\\n"
库中的splitOn "\\n"
来获取.xml文件列表。
然后,我们只需要在该列表上映射getID
(不再需要toList
)。
这给我们:
import Text.Regex.PCRE
import Data.List.Split
getID :: String -> String
getID str = str =~ "([0-9]+)"
main :: IO ()
main = interact $ unlines . map getID . splitOn "\n"
当我运行您的命令时,这给了我想要的输出。
希望这会有所帮助:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.