簡體   English   中英

Data.ByteString.Lazy.Internal.ByteString to string?

[英]Data.ByteString.Lazy.Internal.ByteString to string?

嘗試編寫一個返回計算機外部IP地址的模塊。 使用Network.Wreq get函數,然后應用lense來獲取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)

所以我的問題顯然是:如何將有趣的特殊ByteString轉換為String 解釋我如何自己處理這樣的問題也是值得贊賞的。 我試圖使用unpacktoString但不知道要導入什么來獲取這些函數(如果它們存在)。

作為一個非常零星的haskell用戶,我也想知道是否有人可以向我展示定義這樣一個函數的慣用的haskell方式。 畢竟,我在這里展示的版本沒有考慮可能的運行時錯誤/異常。

簡短回答:使用Data.ByteString.Lazy.Char8中的unpack

更長的回答:

通常,當您想要將ByteString(任何種類)轉換為String或Text時,您必須指定編碼 - 例如UTF-8或Latin1等。

檢索HTML頁面時,您要使用的編碼可能會在Content-type標頭中或響應正文中顯示為<meta ...>標記。

或者你可以猜測身體的編碼是什么。

在你的情況下,我認為你正在訪問像http://whatsmyip.org這樣的網站 ,你只需要解析你的IP地址。 因此,如果不檢查標題或瀏覽HTML,使用的安全編碼將是Latin1。

要通過編碼將ByteStrings轉換為Text,請查看Data.Text.Encoding中的函數

例如, decodeLatin1函數。

我只是不明白為什么你堅持使用String ,當你已經有一個ByteString ,這是更快/更有效的實現。 導入regex幾乎沒有任何好處 - 對於解析ip-address,我會使用attoparsec ,這對ByteString很有用。

這是一個不使用正則表達式但返回一個字符串的版本 - 注意我沒有編譯它因為我現在沒有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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM