【问题标题】:Haskell Bytestring change ASCII?Haskell Bytestring改变ASCII?
【发布时间】:2011-08-18 04:23:36
【问题描述】:
import qualified Data.ByteString.Lazy.Char8 as BS

stuff <- BS.readFile "stuff.txt"

如何从一个字节串中取出一个特定的字符,然后改变它的 ASCII,然后把它放回去? 我使用 readInt 还是什么?

例如:"aaaaa" ,"a" 是 97 所以减去 1 并且你有 "aa`aa"

【问题讨论】:

  • 您应该查看 Data.Text 以获得 unicode 支持。我会用Data.Text.Lazy 替换Data.ByteString.Lazy.Char8 的任何实例并使用Text 支持。 Data.ByteString 应该用于二进制。
  • 请提出一个新问题,而不是将您的问题更改为完全不同的问题。我已恢复编辑,因为它使此处的现有答案变得无关紧要且令人困惑。

标签: haskell ascii bytestring


【解决方案1】:

其他人已经解决了执行字节操作的问题,所以我将专注于您问题的另一半:在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 来实现这一点。现在,我们如何将其翻译为在ByteStrings 上工作?好吧,ByteString 接口提供了takedropsplitAtappendcons;我们唯一没有得到的是我们在上面x:ending 部分中所做的模式匹配。幸运的是,ByteString 确实提供了类似的功能:

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

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

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 -&gt; Word8 参数。尽管您在上面谈论文本,但我要指出,无论如何您都不应该将ByteString 用于文本(ByteStrings 是字节序列,而不是Chars 序列)。因此,如果您选择使用ByteString,您必须谈论的是字节,而不是文本。 ;-)

因此,您真的想问一个将 byte 减一的函数,大概是在边界上环绕。 subtract 1 正是这样的函数,所以要将pack [97, 97, 97, 97, 97] 转换为pack [97, 97, 96, 97, 97],你可以写成onNth 2 (subtract 1)。读起来几乎像英语!

【讨论】:

    【解决方案2】:

    BS.map pred 怎么样?您还可以使用fromEnumtoEnum 转换为/从Ints。

    【讨论】:

    • 在哪个库可以找到 prev?
    • :1:1: 不在范围内:`prev'
    • @Haskeller 对不起,我拼错了。实际上是pred。请注意,pred 不会换行。
    【解决方案3】:

    使用BS.unpack 将字节转换为Chars 后,您可以使用fromEnum :: Char -&gt; Int(或等价于Data.Char 中的ord)将Char 转换为其ASCII 值,然后您可以像普通整数一样对其进行操作。要将 ASCII 值从 Int 转换回 Char,请使用 toEnumData.Char.chr,然后可以使用 BS.pack 或类似名称将 Chars 转换回 ByteString

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 2013-10-04
      相关资源
      最近更新 更多