我有Text
或String
包含文件名,例如/foo/bar/foobar.txt
。
如何定义一个函数extname
(类似于NodeJS's extname,但省略前导点),只产生扩展名(txt
为示例?)
注意:此问题已回答Q& A-Style,因此未显示研究工作。请注意您要改进的内容,而不是低估。
答案 0 :(得分:4)
另一种方法是使用System.Filepath
:
λ> import System.FilePath
λ> snd $ splitExtension "/foo/bar/foobar.txt"
".txt"
您也可以使用@kosmikus指出的takeExtension
:
λ> takeExtension "/foo/bar/foobar.txt"
".txt"
答案 1 :(得分:1)
您可以像这样定义extname
的基本版本:
{-# LANGUAGE OverloadedStrings #-}
import Data.Text (Text)
import qualified Data.Text as T
extname :: Text -> Text
extname = T.reverse . T.takeWhile ((/=) '.') . T.reverse
或String
(别名为FilePath
):
extname :: FilePath -> FilePath
extname = reverse . takeWhile ((/=) '.') . reverse
extname
可能存在的问题是如何处理错误(即您对正确错误处理的定义是什么)。例如,这里发布的函数将返回整个文件名,包括路径,如果函数中没有点。
例如,extname "/etc/foo.d/config" == "d/config"
。
将extname
与basename
相结合可以解决此特定问题(我只会在此处显示Text
版本):
import Filesystem.Path.CurrentOS (fromText, toText)
import Filesystem.Path (basename)
extname' = extname . toText . basename . fromText
屈服于extname' "/etc/foo.d/config" == "config"
。
如果需要前导点(即模仿NodeJS行为),请使用:
import Data.Monoid (mappend)
extnameWithDot filename = "." `mappend` extname' filename