Delphi-从字符串中删除特定的十六进制值

时间:2018-10-04 18:49:21

标签: delphi hex

Delphi Tokyo-我有一个文本文件...(特别是CSV文件)。我正在使用TextFile操作逐行读取文件...文件的前三个字节具有某些我不感兴趣的标头数据类型。尽管我认为所有文件都是这种情况,但我想验证一下在我删除它之前。简而言之,我想读取该行,将前三个字节与三个十六进制值进行比较,如果匹配,则删除这三个字节。

当我在十六进制编辑器中查看文件时,会看到

EF BB BF ...

无论出于何种原因,我的比较均不起作用。 这是一个代码片段。

var
LeadingBadBytes: String;
begin

 // Open file, and read first line into variable TriggerHeader
 ...
 LeadingBadBytes := '$EFBBBF';
 if AnsiPos(LeadingBadBytes, TriggerHeader) = 1 then    
   delete(TriggerHeader, 1, 3);

DELETE命令本身可以正常工作,但是我无法使AnsiPos正常工作。我该怎么做?

1 个答案:

答案 0 :(得分:7)

字节EF BB BF是UTF-8 BOM,用于将文件标识为以UTF-8编码的Unicode文本。它们仅出现在文件的开头,而不是出现在每一行。

您的比较不起作用,因为您正在将读取的字符串与文字字符串 '$EFBBBF'进行比较,而不是与字节序列 EF BB BF进行比较。

更改此:

LeadingBadBytes := '$EFBBBF';
...
Delete(TriggerHeader, 1, 3);

对此:

LeadingBadBytes := #$FEFF; // EF BB BF is the UTF-8 encoded form of Unicode codepoint U+FEFF...
...
Delete(TriggerHeader, 1, 1); // or Delete(..., Length(LeadingBadBytes))

另外,考虑使用StrUtils.StartsText(...)代替AnsiPos(...) = 1

话说回来,现代版本的Delphi应该为您处理BOM,您根本不应该在读取的数据中接收它。但是,由于您说的是使用TextFile,因此它不是可识别BOM的AFAIK。首先,您不应该使用过时的 Pascal样式的文件I / O。尝试使用更现代的Delphi RTL I / O类,例如TStringListTStreamReader,它们都支持BOM。