【问题标题】:Replacing a unicode character in UTF-8 file using delphi 2010使用delphi 2010替换UTF-8文件中的unicode字符
【发布时间】:2012-12-13 21:38:27
【问题描述】:

我正在尝试用字符(十进制值 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;

【问题讨论】:

  • UTF-8 是一个字节长度,因此除非是代理对,否则不可能有十进制值 300,在这种情况下,最好讨论代表字符的代码点或单个字节。无论如何,您要完成什么,因为它可能与您的other question 有关
  • 这些都没有任何意义。这个问题或您的其他问题。您在问什么是XY question。我敦促你告诉我们背后的故事。说出根本问题。让我们提出一个解决方案。您提出的解决方案听起来很弱。
  • 普通的旧 StringReplace 有什么问题?
  • 转成字符串,也就是UTF16,使用StringReplace,然后再保存为UTF8或者ASCII。
  • @JakeSnake:字节八位字节序列 C5 9E(dec 197 158)是 UTF-8 编码的 Ş Unicode 字符,而不是 Å 字符。如果您只是将C5 替换为41(12 月65 日),但不理会9E,则将Ş 转换为无效的UTF-8 序列。我怀疑那是你真正想要的。如果你想用41替换C5 9E,你必须解码UTF-8数据,然后你可以使用StringReplace()Ş字符替换为A字符,然后将结果编码回UTF -8.

标签: delphi delphi-2010


【解决方案1】:

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

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

U+00C5 以 UTF-8 编码为C3 85U+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;

更新: 基于其他 cmets,看起来您实际上对 Unicode 代码点 U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE 并不感兴趣,而是对 U+015E LATIN CAPITAL LETTER S WITH CEDILLA 感兴趣,它以 UTF-8 编码为 @987654338 @。如果是这样,那么在解码 UTF-8 数据后调用 StringReplace() 时,只需将 Å 替换为 Ş

S := StringReplace(S, 'Ş', 'A', [rfReplaceAll]);

【讨论】:

  • 杰克指的是U+015E
猜你喜欢
  • 1970-01-01
  • 2014-09-22
  • 2013-01-21
  • 1970-01-01
  • 2018-06-12
  • 2012-02-22
  • 2019-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多