Hintergrund meines Ausgangsprojekts ist, dass Worte wie " Floß" zu "Floß" oder "Flöhe springen 13 " zu "Flöhe springen" gekürzt werden. Sprich, ich will alle Leerzeichen, Zahlen, Steuerzeichen etc. vor und nach Wörtern entfernen und nur die Wörter erhalten. Ich hatte auch schon Theos UTF8Tools angeschaut und dort die Function "IsLetter" angeschaut, was prinzipiel genau das machen tät, was ich brauch. Allerdings gibt es Probleme, wenn ich die Strings von hinten bereinigen will und ein Sonderzeichen als letztes steht z.B. "ß" bei "Floß" -> das "ß" ist zwei Byte lang, daher ist Str[4] und Str[5] das "ß", sodaß die Byte-weise Durchsicht des Strings von hinten nach vorn nicht geht. Daher dachte ich, ich wandel den Text einfach nach Ansi um, teste dort Byte-weise, lösche ungültige Zeichen und wandel wieder zurück nach UTF8. Gesagt, getan, alles prima, bis ich den String in der Datenbank abfragen will:
Ich habe das Ganze auf folgendes Minimalbsp. reduziert (neue Form, Zconnection und ZQuery drauf):
Code: Alles auswählen
procedure SchreibeByte(Str:String);
var
i: Integer;
S: String;
begin
S:='';
for i:=0 to High(Str) do
S:=S + '[' + IntToHex(Byte(Str[i]), 2) + '] ';
Writeln(S);
end;
procedure TForm1.TestSelect;
begin
ZConnection1.Connected:=True;
ZQuery1.SQL.Text:='SELECT beschreibung FROM warentabelle WHERE warenname='''+Str+''';';
ZQuery1.Open;
Caption:='Suchwort['+Str+'] - Ergebnis['+ZQuery1.Fields[0].AsString+']';
ZQuery1.Close;
end;
procedure TForm1.FormCreate(Sender: TObject);
var
S: AnsiString;
begin
Str:='Möhre';
Writeln('String vor Konvertierung:');
SchreibeByte(Str);
TestSelect;
S:=UTF8ToAnsi(Str);
Str:=UTf8Encode(S);
Writeln('String nach Konvertierung:');
SchreibeByte(Str);
readln;
TestSelect; //Hier gibt die Exception, siehe angehangenes Bild
end;
Procedure "TestSelect" versucht etwas aus der Datenbank auszulesen
Beim "FormCreate" startet das Programm:
- es wird "Möhre" als String gesetzt
- die Zeichen des Strings werden im Konsolenfenster ausgegeben
- die Datenbank wird getestet -> funktioniert!!! (auch mit "Möhre")
- der String wird einmal zu Ansi und wieder zurück zu UTF8 konvertiert
- die Zeichen des Strings werden im Konsolenfenster ausgegeben (Die Zeichen sind identisch mit der ersten Ausgabe in der Konsole!!!, siehe unten angehangenes Bild)
- die Datenbank wird erneut getestet, dabei kommt es zum Fehler (siehe angehangenes Bild), die Zeichenkodierung entspricht nicht dem der in der Konsole ausgegebenen Kodierung!
Meine Vermutung ist, dass irgend etwas bei der Konvertierung von Ansi zu UTF8 im Header des Strings stehen geblieben sein muss, dass der String nicht ordentlich als UTF8 gelesen wird?!
Kann jemand den Fehler bestätigen (der konvertierte String fehlerfrei bei "Caption:=Str" angezeigt, Ärger gibts nur bei der Datenbankabfrage)?!
Hat jemand eine Idee zur Problembeseitigung?
Ich nutze Lazarus 1.3 r43268 FPC 2.7.1 (Trunc 25806) i386-win32-win32/win64, ZEOS 7.1.2
Danke