繁体   English   中英

如何在Haskell中使用此正则表达式?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM