通过TestRing从Haskell中删除BOM的最简单方法

通过TestRing从Haskell中删除BOM的最简单方法,haskell,character-encoding,byte-order-mark,bytestring,Haskell,Character Encoding,Byte Order Mark,Bytestring,我有一个可能是从。通过testring从这个中删除BOM的最简单、最好的有效方法是什么?我觉得我一定是误解了这个问题。这不是归结为检查bytestring的前三个字节并有条件地删除这些字节吗 要获取前3个字节,请使用take 要检查bytestring是否相等,请使用(==) 要删除前3个字节,请使用drop 把这些放在一起,我们得到: import Data.ByteString.Lazy as BS dropBOM bs | BS.take 3 bs == BS.pack [0xEF,0

我有一个可能是从。通过testring从这个
中删除BOM的最简单、最好的有效方法是什么?

我觉得我一定是误解了这个问题。这不是归结为检查bytestring的前三个字节并有条件地删除这些字节吗

  • 要获取前3个字节,请使用
    take
  • 要检查bytestring是否相等,请使用
    (==)
  • 要删除前3个字节,请使用
    drop
把这些放在一起,我们得到:

import Data.ByteString.Lazy as BS
dropBOM bs | BS.take 3 bs == BS.pack [0xEF,0xBB,0xBF] = BS.drop 3 bs
           | otherwise = bs

然而,即使在处理了大量utf8之后,我也从未觉得需要显式地处理BOM,因为像文本这样的包提供了最理想的操作。也许你可以用另一种方法来解决你的问题,而不是手动咀嚼bytestring。

BOM表不是一个特殊的字符吗?不适用于此?@Alec嗯,首先我需要检查我的字符串是否以BOM开头。BOM是3个字节(即大小为3的
Word8
列表),并且
head
具有类型
head::ByteString->Word8
。非常奇怪的是,
head
只返回一个字节,而
tail
可以删除几个字节。所以我想只是
tail
是行不通的。另外,
tail
如果给定的
ByteString
为空,则抛出纯异常,这不是我想要的:)@Shersh,这样您就知道该做什么了。为什么不在问这个问题之前试试呢?哎呀。是的,我明白你的问题了。查看
utf8字符串
软件包。您可以检查bytestring是否为空,如果它不是
uncon
。根据返回的第一个字符,您可以返回尾部(也可以从
uncon
)或初始bytestring。谢谢您的回答!您的解决方案非常简单高效(因为
获取
删除
不分配内存)。我个人提出了更糟糕的解决方案。。。当我需要解析CSV文件时,我遇到了
木薯
软件包的问题。不幸的是,此库无法处理BOM:(尽管如此,您的解决方案不太有效,因为
解包“BOM”=[66,79,77]
,而字节顺序标记是
[239187191]
。嘿,是的,这是一个猜测。使用您想要的任何常量。编辑:修复(?)@Shersh没有说明他们期望的编码是什么。这个方案对于UTF-8是正确的(在这个答案中明确地指出这一点可能很好),但对于UTF-16来说就不是这样了,在UTF-16中,魔法字节是不同的,并且非常关键地用于指示endianness(因此,即使您只想去除它们,也不能进行一次相等性检查)@jberryman是的,你说得对。编码很容易出错……希望我有
utf-8
encoding:)