尝试编写一个返回计算机外部IP地址的模块.使用Network.Wreq get函数,然后应用镜头获取responseBody,我最终得到的类型是Data.ByteString.Lazy.Internal.ByteString.因为我想过滤掉结果体的尾随"\n",我想随后将它用于正则表达式.问题:regex库不接受看似非常具体的ByteString类型,我发现无法将其转换为String.
这是我到目前为止的微弱尝试(不编译).
{-# LANGUAGE OverloadedStrings #-}
module ExtIp (getExtIp) where
import Network.Wreq
import Control.Lens
import Data.BytesString.Lazy
import Text.Regex.Posix
getExtIp :: IO String
getExtIp = do
r <- get "http://myexternalip.com/raw"
let body = r ^. responseBody
let addr = body =~ "[^\n]*\n"
return (addr)
Run Code Online (Sandbox Code Playgroud)
所以我的问题很明显:如何将有趣的特殊ByteString转换为String?解释我如何自己处理这样的问题也是值得赞赏的.我试图用unpack和toString,但不知道该怎么导入如果它们存在让这些功能.
作为一个非常零星的haskell用户,我也想知道是否有人可以向我展示定义这样一个函数的惯用的haskell方式.毕竟,我在这里展示的版本没有考虑可能的运行时错误/异常.
Eri*_*ikR 11
简短回答:使用unpackData.ByteString.Lazy.Char8
更长的回答:
通常,当您想要将ByteString(任何种类)转换为String或Text时,您必须指定编码 - 例如UTF-8或Latin1等.
检索HTML页面时,您要使用的编码可能会作为<meta ...>标记显示在Content-type标头中或响应正文中.
或者你可以猜测身体的编码是什么.
在你的情况下,我认为你正在访问像http://whatsmyip.org这样的网站,你只需要解析你的IP地址.因此,如果不检查标题或浏览HTML,使用的安全编码将是Latin1.
要通过编码将ByteStrings转换为Text,请查看Data.Text.Encoding中的函数
例如,decodeLatin1功能.
我根本不明白为什么你坚持使用Strings,当你ByteString手头已经有了更快/更有效的实现。导入regex几乎没有给你带来任何好处——为了解析 ip 地址,我会使用attoparsec它,它与ByteStrings 配合得很好。
这是一个不使用正则表达式但返回字符串的版本 - 注意我没有编译它,因为我现在没有 haskell 设置。
{-# LANGUAGE OverloadedStrings #-}
module ExtIp (getExtIp) where
import Network.Wreq
import Control.Lens
import Data.ByteString.Lazy.Char8 as Char8
import Data.Char (isSpace)
getExtIp :: IO String
getExtIp = do
r <- get "http://myexternalip.com/raw"
return $ Char8.unpack $ trim (r ^. responseBody)
where trim = Char8.reverse . (Char8.dropWhile isSpace) . Char8.reverse . (Char8.dropWhile isSpace)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4401 次 |
| 最近记录: |