Haskell Bytestring改变ASCII?

时间:2011-08-16 19:09:34

标签: haskell ascii bytestring

import qualified Data.ByteString.Lazy.Char8 as BS

stuff <- BS.readFile "stuff.txt"

如何从bytestring中获取特定字符然后更改其ASCII然后将其放回? 我是否使用readInt?

Ex:“aaaaa”,“a”是97,所以减1并且你有“aa`aa”

3 个答案:

答案 0 :(得分:2)

BS.map pred怎么样?您还可以使用fromEnumtoEnum转换为Int的转换。

答案 1 :(得分:2)

其他人已经解决了执行字节操作的问题,因此我将重点关注问题的另一半:选择并更新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 s?好吧,ByteString界面提供了takedropsplitAtappendcons;我们唯一没有得到的是我们在上面的x:ending部分中进行的模式匹配。幸运的是,ByteString确实提供了类似的东西:

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

因此,使用它,我们可以编写一个适用于onNth的新ByteString函数:

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

最后,我们可以讨论我们应该使用哪个函数作为上面的f :: Word8 -> Word8参数。虽然您在谈论上面的文字,但我会指出您不应该使用ByteString作为文本(ByteString s是字节序列,而不是Char s的序列。因此,如果您选择使用ByteString,则必须讨论字节而不是文本。 ; - )

因此,你真的想问一个将字节减少一个的函数,可能是在边界上缠绕。 subtract 1是一个完全相同的功能,因此要将pack [97, 97, 97, 97, 97]转换为pack [97, 97, 96, 97, 97],您可以编写onNth 2 (subtract 1)。阅读几乎像英语!

答案 2 :(得分:1)

使用Char将字节转换为BS.unpack后,您可以使用fromEnum :: Char -> Int(或等效地ord来自Data.Char)将Char转换为其ASCII值,然后可以像普通整数一样进行操作。要将Int的ASCII值转换回Char,请使用toEnumData.Char.chr,然后可以将Char转换回{ {1}} ByteString或类似内容。