Lazarus:StringReplace在处理文件时无效(unicode问题)
我正在使用Lazarus构建一个基于模板构建Outlook签名的简单应用程序。其思想是提取模板(一个ZIP文件),并替换其中包含的文件中的变量 例如,我可能想用用户提供的名称替换Lazarus:StringReplace在处理文件时无效(unicode问题),string,replace,lazarus,fpc,delphi,String,Replace,Lazarus,Fpc,Delphi,我正在使用Lazarus构建一个基于模板构建Outlook签名的简单应用程序。其思想是提取模板(一个ZIP文件),并替换其中包含的文件中的变量 例如,我可能想用用户提供的名称替换{fullname} 我目前正在使用下面的实现,但它似乎无效。文件已读写,但似乎未进行替换。我已经测试了TFileStream的实现是否不正确,但是使用writeansisting将伪文本附加到输出文件的末尾是有效的 请您看一下我下面的代码,告诉我我可能做错了什么,或者是否有更好的替代方法来代替StringReplace
{fullname}
我目前正在使用下面的实现,但它似乎无效。文件已读写,但似乎未进行替换。我已经测试了TFileStream
的实现是否不正确,但是使用writeansisting
将伪文本附加到输出文件的末尾是有效的
请您看一下我下面的代码,告诉我我可能做错了什么,或者是否有更好的替代方法来代替StringReplace
?我知道可以使用TStringList
——但是这样做会破坏行尾。由于备忘录和丰富的编辑使用的是TStringList
,使用它们也不会有帮助
更新:
我看到了,但是使用AnsiString
没有什么区别。如果我没有弄错的话,FPC默认使用它,而不是UnicodeString
更新2:
实际上,AnsiString
是默认设置。使用unicode字符串(使替换工作正常)将?
添加到文件的开头和结尾。为什么会这样
函数multiStringReplace(常量s:string;搜索、替换:字符串数组;标志:tReplaceFlags):字符串;
变量c:基数;
开始
断言(长度(搜索)=长度(替换),‘数组长度不同’;
结果:=s;
对于c:=低(搜索)到高(搜索)do
结果:=stringReplace(结果,搜索[c],替换[c],标志);
结束;
过程文件替换字符串(常量文件名:字符串;搜索,替换:字符串数组);
变量
fs:tFileStream;
s:字符串;
开始
fs:=tFileStream.create(文件名、fmOpenRead或fmsharedynone);
尝试
设置长度(s,fs.大小);
fs.readBuffer(s[1],fs.size);
最后
fs.free();
结束;
s:=multiStringReplace(s,搜索,替换,[rfReplaceAll,rfIgnoreCase]);
fs:=tFileStream.create(文件名,fmOpenWrite);
尝试
fs.writeBuffer(s[1],长度(s));
最后
fs.free();
结束;
结束;
用法:
fileReplaceString(当前文件,['{fullname}'],['Full Name']);
多亏了Abelisto的上述评论,问题似乎是因为Outlook使用不同的编码保存了它创建的三个文件。为了解决这个问题,我只使用了lconverncoding
中的convertcoding
和guessEncoding
,如下所示:
使用
l转换编码;
//读取字符串
s:=convertEncoding(
多字符串替换(s,搜索,替换,[rfReplaceAll,rfIgnoreCase]),
猜测编码,编码ANSI
);
//将修改和转换的字符串写回文件
编码ANSI
似乎是最好的转换,至少在我的情况下是这样。转换为UTF8(带或不带BOM)会让某些字符感到头疼,特别是EmDash或EnDash。模板文件是否包含UTF16文本?如果是-尝试将其重新编码为UTF8(Lazarus的本机编码)。Outlook生成的.txt
文件似乎确实是UTF-16LE(而.htm
文件是Windows-1252)。我怎样才能检查相关文件的编码并进行相应转换?例如,关于文本转码,您可以阅读。然而,对于我的UTF-16LE函数中的小测试文件,由于未知原因,GuessEncoding
返回utf8
。使用硬编码源代码可以很好地工作:ShowMessage(ConvertEncoding(s,EncodingUCS2LE,EncodingUTF8))代码>不要忘记使用l转换编码
单元。谢谢!这看起来确实很有用-明天我们将尝试一下,并向您汇报。@Abelisto-这确实很有用,谢谢。刚刚使用的s:=convertEncoding(s,guessEncoding(s),encodingUTF8)代码>更换前,现在一切正常。而前景似乎并不反对。