簡體   English   中英

Haskell 字節串更改 ASCII?

[英]Haskell Bytestring change ASCII?

import qualified Data.ByteString.Lazy.Char8 as BS

stuff <- BS.readFile "stuff.txt"

如何從字節串中獲取特定字符,然后更改其 ASCII,然后將其放回原處? 我使用 readInt 還是什么?

例如:“aaaaa”,“a”是 97,所以減去 1,你有“aa`aa”

BS.map pred怎么樣? 您還可以使用fromEnumtoEnum轉換為 / 從Int s。

其他人已經解決了執行字節操作的問題,所以我將專注於您問題的另一半:選擇和更新ByteString中的特定字節。 讓我們開始使用更熟悉的界面來實現普通列表的操作:

onNth :: Int -> (a -> a) -> ([a] -> [a])
onNth n f xs = case splitAt n xs of
    (beginning, x:ending) -> beginning ++ f x : ending
    _ -> xs -- happens when n is out-of-bounds

您可以等效地使用takedrop而不是splitAt來實現這一點。 現在,我們如何將其翻譯為在ByteString上工作? 好吧, ByteString接口提供了takedropsplitAtappendcons 我們唯一沒有得到的是我們在上面的x:ending部分中所做的模式匹配。 幸運的是, ByteString確實提供了類似的東西:

uncons :: ByteString -> Maybe (Word8, ByteString)

因此,使用它,我們可以編寫一個適用於ByteString的新onNth function:

second :: (b -> c) -> (a, b) -> (a, c)
second f (a, b) = (a, f b)

onNth :: Int -> (Word8 -> Word8) -> (ByteString -> ByteString)
onNth n f bs = case second uncons (splitAt n bs) of
    (beginning, Just (x, ending)) -> append beginning (cons (f x) ending)
    _ -> bs -- again, for out-of-bounds cases

最后,我們可以討論我們應該使用什么 function 作為上面的f:: Word8 -> Word8參數。 盡管您在上面談論文本,但我會指出您無論如何都不應該將ByteString用於文本( ByteString是字節序列,而不是Char序列)。 因此,如果您選擇使用ByteString ,那么您一定是在談論字節,而不是文本。 ;-)

因此,你真的想問一個 function 一個字節減少一個,大概是在邊界上環繞。 subtract 1是一個 function 正是這樣做的,所以要將pack [97, 97, 97, 97, 97]轉換為pack [97, 97, 96, 97, 97] ,你可以寫onNth 2 (subtract 1) 讀起來幾乎像英語!

使用 BS.unpack 將字節轉換為Char后,您可以使用BS.unpack fromEnum:: Char -> Int (或者,等效地,從Data.Char中的ord )將Char轉換為其 ASCII 值,然后您可以對其進行操作像普通的 integer。 要將 ASCII 值從Int轉換回Char ,請使用toEnumData.Char.chr ,然后可以使用BS.pack或類似方法將Char轉換回ByteString

暫無
暫無

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

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