[英]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
怎么樣? 您還可以使用fromEnum
和toEnum
轉換為 / 從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
您可以等效地使用take
和drop
而不是splitAt
來實現這一點。 現在,我們如何將其翻譯為在ByteString
上工作? 好吧, ByteString
接口提供了take
、 drop
、 splitAt
、 append
和cons
; 我們唯一沒有得到的是我們在上面的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
,請使用toEnum
或Data.Char.chr
,然后可以使用BS.pack
或類似方法將Char
轉換回ByteString
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.