Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Lazarus:StringReplace在处理文件时无效(unicode问题)_String_Replace_Lazarus_Fpc_Delphi - Fatal编程技术网

Lazarus:StringReplace在处理文件时无效(unicode问题)

Lazarus:StringReplace在处理文件时无效(unicode问题),string,replace,lazarus,fpc,delphi,String,Replace,Lazarus,Fpc,Delphi,我正在使用Lazarus构建一个基于模板构建Outlook签名的简单应用程序。其思想是提取模板(一个ZIP文件),并替换其中包含的文件中的变量 例如,我可能想用用户提供的名称替换{fullname} 我目前正在使用下面的实现,但它似乎无效。文件已读写,但似乎未进行替换。我已经测试了TFileStream的实现是否不正确,但是使用writeansisting将伪文本附加到输出文件的末尾是有效的 请您看一下我下面的代码,告诉我我可能做错了什么,或者是否有更好的替代方法来代替StringReplace

我正在使用Lazarus构建一个基于模板构建Outlook签名的简单应用程序。其思想是提取模板(一个ZIP文件),并替换其中包含的文件中的变量

例如,我可能想用用户提供的名称替换
{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)更换前,现在一切正常。而前景似乎并不反对。