J'utilise Lazarus pour créer une application simple qui construit des signatures Outlook basées sur un modèle. L'idée est d'extraire le modèle (un fichier ZIP) et de remplacer les variables dans les fichiers qu'il contient.Lazarus: StringReplace inefficace lorsque vous travaillez avec des fichiers (problème unicode)
Par exemple, je souhaite remplacer {fullname}
par le nom fourni par l'utilisateur. J'utilise actuellement l'implémentation ci-dessous, mais elle semble inefficace. Le fichier est lu et écrit, mais il semble que les remplacements ne sont pas faits. J'ai testé pour voir si ma mise en œuvre de TFileStream
n'est pas correcte, mais en utilisant WriteAnsiString
pour ajouter du texte factice sur la fin du fichier de sortie fonctionne.
S'il vous plaît veuillez regarder mon code ci-dessous et laissez-moi savoir ce que j'ai pu faire de mal, ou s'il y a de meilleures alternatives à StringReplace
? Je suis conscient que l'on peut utiliser TStringList
- cependant, cela casse les fins de ligne. Comme les mémos et les éditions riches utilisent TStringList
, l'utilisation de ceux-ci n'aidera pas non plus.
Mise à jour:
J'ai vu this, mais en utilisant AnsiString
ne fait aucune différence. Si je ne me trompe pas, FPC l'utilise par défaut de toute façon, au lieu de UnicodeString
.
Mise à jour 2:
En effet, AnsiString
est la valeur par défaut. L'utilisation d'une chaîne unicode (qui fait fonctionner les remplacements) ajoute ?
au début et à la fin du fichier. Pourquoi ferait-il ça?
function multiStringReplace(const s: string; search, replace : array of string; flags : tReplaceFlags): string;
var c : cardinal;
begin
assert(length(search) = length(replace), 'Array lengths differ.');
result := s;
for c := low(search) to high(search) do
result := stringReplace(result, search[c], replace[c], flags);
end;
procedure fileReplaceString(const fileName: string; search, replace: array of string);
var
fs: tFileStream;
s: string;
begin
fs := tFileStream.create(fileName, fmOpenRead or fmShareDenyNone);
try
setLength(s, fs.size);
fs.readBuffer(s[1], fs.size);
finally
fs.free();
end;
s := multiStringReplace(s, search, replace, [rfReplaceAll, rfIgnoreCase]);
fs := tFileStream.create(fileName, fmOpenWrite);
try
fs.writeBuffer(s[1], length(s));
finally
fs.free();
end;
end;
Utilisation:
fileReplaceString(currentFile, ['{fullname}'], ['Full Name']);
Votre fichier modèle contient-il du texte UTF16? Si oui, essayez de le recoder en UTF8 (codage natif pour Lazarus). – Abelisto
Il semble que le fichier '.txt' généré par Outlook soit en fait UTF-16LE (alors que le fichier' .htm' est Windows-1252). Comment puis-je choisir l'encodage du fichier en question et le convertir en conséquence? –
A propos du transcodage de texte, vous pouvez lire [ici] (http://wiki.lazarus.freepascal.org/Multiplatform_Programming_Guide#Text_encoding) par exemple. Cependant, pour mon petit fichier de test dans la fonction UTF-16LE, 'GuessEncoding' renvoie' utf8' pour une raison inconnue.L'utilisation du codage source codé en dur fonctionne bien: 'ShowMessage (ConvertEncoding (s, EncodingUCS2LE, EncodingUTF8));' Ne pas oublier d'utiliser l'unité 'LConvEncoding'. – Abelisto