1

我正在尝试用字符(十进制值 65)替换 UTF-8 文件中的字符(十进制值 197)

我可以加载文件并将其放入字符串中(尽管可能不需要这样做)

SS := TStringStream.Create(ParamStr1, TEncoding.UTF8);
SS.LoadFromFile(ParamStr1);
//S:= SS.DataString;
//ShowMessage(S);

但是,如何将所有 197 替换为 65,并将其另存为 UTF-8?

 SS.SaveToFile(ParamStr2);
 SS.Free;

- - - - - - - 编辑 - - - - - - - -

reader:= TStreamReader.Create(ParamStr1, TEncoding.UTF8);
 writer:= TStreamWriter.Create(ParamStr2, False, TEncoding.UTF8);

 while not Reader.EndOfStream do
 begin
  S:= reader.ReadLine;
  for I:= 1 to Length(S)  do
  begin
   if Ord(S[I]) = 350 then
   begin
    Delete(S,I,1);
    Insert('A',S,I);
   end;
  end;
  writer.Write(S + #13#10);
 end;

 writer.Free;
 reader.Free;
4

1 回答 1

7

十进制197是十六进制C5,十进制65是十六进制41

C5本身不是一个有效的 UTF-8 八位字节,但41它是。所以我不得不假设你实际上指的是 Unicode 代码点U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE,而U+0041 LATIN CAPITAL LETTER A不是。

U+00C5在 UTF-8 中编码为C3 85,并被U+0041编码为41。要执行您的要求,您必须解码 UTF-8,替换代码点,然后重新编码回 UTF-8。 StringReplace()可以很好地解决这个问题,例如:

SS := TStringStream.Create('', TEncoding.UTF8);
SS.LoadFromFile(ParamStr1);

S := StringReplace(SS.DataString, 'Å', 'A', [rfReplaceAll]);

SS2 := TStringStream.Create(S, TEncoding.UTF8);
SS2.SaveToFile(ParamStr2);

SS2.Free;
SS.Free;

或者:

reader := TStreamReader.Create(ParamStr1, TEncoding.UTF8);
writer := TStreamWriter.Create(ParamStr2, False, TEncoding.UTF8);

while not Reader.EndOfStream do
begin
  S := reader.ReadLine;
  S := StringReplace(S, 'Å', 'A', [rfReplaceAll]);
  writer.WriteLine(S);
end;

writer.Free;
reader.Free;

更新:根据其他评论,看起来您实际上对 Unicode codepoint 并不感兴趣U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE,而是对U+015E LATIN CAPITAL LETTER S WITH CEDILLA以 UTF-8 编码为C5 9E. 如果这是真的,那么在 UTF-8 数据解码后调用时只需替换Å为:ŞStringReplace()

S := StringReplace(S, 'Ş', 'A', [rfReplaceAll]);
于 2012-12-13T23:02:03.577 回答