Erkennen ob das Zeichen ein UTF8 Zeichen ist

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von theo »

pluto hat geschrieben:Zum Festhalten:
Ich muss Praktisch bevor ich auf eine Variable zugreife ersteinmal ein UTF8Decode durchführen um sicherzugehen das es sich um ein UTF8String handelt. Richtig ?
Nein. Erstmal musst du dich entscheiden, ob du in deinem Programm intern mit WideString (UCS2) oder String (UTF-8) arbeiten willst.
Mit UTF-8 musst du nicht umwandlen.
Bei WideString musst du nur umwandeln, wenn du mit der LCL kommunizierst. Zur LCL gehört auch der IDE Editor.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von pluto »

Dann bin ich genauso weit wie Vorher. :(
MFG
Michael Springwald

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von theo »

pluto hat geschrieben:Dann bin ich genauso weit wie Vorher. :(
Wieso?

Du weisst nun, dass du deinen Code bereinigen musst.

Du hast da Sachen drin, die gibt's einfach nicht

z.B.

str:widestring;
...
begin
...
c:=UTF8Length(str);

macht keinen Sinn. Ein UTF-8 String sollte nicht in einem WideString sein.

creed steiger
Beiträge: 958
Registriert: Mo 11. Sep 2006, 22:56

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von creed steiger »

pluto hat geschrieben:Dann bin ich genauso weit wie Vorher. :(
Langsam versteh ich dich nimmer.
Dein Problem war doch das du
mit z.b.
s[5] nicht auf ein einzelnes Zeichen in deinem String zugreifen konntest,oder?
(bzw das die Length bei Umlauten falsch war)

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von Socke »

pluto hat geschrieben:Zum Festhalten:
Ich muss Praktisch bevor ich auf eine Variable zugreife ersteinmal ein UTF8Decode durchführen um sicherzugehen das es sich um ein UTF8String handelt. Richtig ?
Wenn du einen Quelltext-String in einen WideString speichern willst, musst du diesen erst mit UTF8Decode() in UCS2 kodieren.
So könnte man überprüfen, ob ein UTF-8-Zeichen in einem WideString vorkommt:

Code: Alles auswählen

{ überprüft ob das UTF-8 Zeichen c in s vorkommt (String, da ein Zeichen aus mehreren Bytes bestehen kann }
function ContainsUTF8Char(const s: Widestring; const c: String): Integer;
var i: Integer;
     c2: WideString;
begin
  // standard Rückgabewert
  Result := -1;
  // abbrechen, wenn einer der Strings keinen Inhalt hat
  if (length(s) = 0) or (length(c) = 0) then
   exit;
  // c in UCS2 kodieren
  c2 := UTF8Decode(c);
  // Exception auslösen, wenn mehr als ein Zeichen übergeben wurden
  // auch ein UTF-8-Multibyte-Zeichen sollte in UCS2 kodiert immer 2Byte, d.h. einen WideChar, belegen
  if length(c2) > 1 then
    raise Exception.Create('ContainsUTF8Char: der Parameter "const c: String" darf nur einen UTF-8 kodierten Buchstaben enthalten (auch Multibyte-Zeichen)');
  for i := length(s) downto 1 do begin
  // und dann überprüfen
  // wichtig: c2 (das umkodierte UTF-8-Zeichen) ist auch ein String; deshalb c2[1]
    if s[i] = c2[1] then begin
      Result := i;
      break;
    end;
  end;
end;
Probleme könnte es noch bei Unicode-Zeichen geben, die in UCS2 nicht oder mit Surrogate kodiert werden. Bei denen weiß ich aber nicht, was UTF8Decode() damit macht.

MfG Socke
P.S.
creed steiger hat geschrieben:Dein Problem war doch das du
mit z.b.
s[5] nicht auf ein einzelnes Zeichen in deinem String zugreifen konntest,oder?
(bzw das die Length bei Umlauten falsch war)
Nach UTF8Decode liegt der UTF-8 String in einem WideString (UCS-2) vor und man kann mit ws auf ein Zeichen (auch umlaute) zugreifen
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

creed steiger
Beiträge: 958
Registriert: Mo 11. Sep 2006, 22:56

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von creed steiger »

Socke hat geschrieben:

P.S.
creed steiger hat geschrieben:Dein Problem war doch das du
mit z.b.
s[5] nicht auf ein einzelnes Zeichen in deinem String zugreifen konntest,oder?
(bzw das die Length bei Umlauten falsch war)
Nach UTF8Decode liegt der UTF-8 String in einem WideString (UCS-2) vor und man kann mit ws auf ein Zeichen (auch umlaute) zugreifen


Genau.
Soweit waren wir ja schon auf der ersten Seite.
Drum kann ich Plutos Problem langsam nicht mehr nachvollziehen.

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von theo »

creed steiger hat geschrieben: Drum kann ich Plutos Problem langsam nicht mehr nachvollziehen.
Verstand wird Rußland nie verstehn,
Kein Maßstab sein Geheimnis rauben;
So wie es ist, so laßt es gehn -
An Rußland kann man nichts als glauben.

Der kühle, wägende Verstand
Kann Rußlands Wesen nicht verstehen;
Denn daß es heilig ist, dies Land,
Das kann allein der Glaube sehen.

Fjodor Iwanowitsch Tjutschew

creed steiger
Beiträge: 958
Registriert: Mo 11. Sep 2006, 22:56

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von creed steiger »

theo hat geschrieben:
creed steiger hat geschrieben: Drum kann ich Plutos Problem langsam nicht mehr nachvollziehen.
Verstand wird Rußland nie verstehn,
Kein Maßstab sein Geheimnis rauben;
So wie es ist, so laßt es gehn -
An Rußland kann man nichts als glauben.

Der kühle, wägende Verstand
Kann Rußlands Wesen nicht verstehen;
Denn daß es heilig ist, dies Land,
Das kann allein der Glaube sehen.

Fjodor Iwanowitsch Tjutschew
Schön das du's mit Humor nimmst :)
Edit:(Gib zu,auf die Gelegenheit das zu posten hast du schon länger
gewartet) ;)
Zuletzt geändert von creed steiger am Di 6. Jan 2009, 20:49, insgesamt 1-mal geändert.

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von theo »

Ich hab noch mehr Poesie auf Lager:

Warum verstehn sie's denn nicht, warum?
Es ist ja doch klar zu sehen!
Ei was, sie schnüffeln nur dran herum,
Und wollen's gar nicht verstehen!

Vergnüglicher ist der Mißverstand,
Dem Troß und seinem Geschwister;
Im Blödsinn reichen sich lächelnd die Hand
Herr Leichtfuß und Herr Philister.

Otto Roquette
creed steiger hat geschrieben: Edit:(Gib zu,auf die Gelegenheit das zu posten hast du schon länger
gewartet) ;)
Nichts geb ich zu.. ;-)

Christian
Beiträge: 6079
Registriert: Do 21. Sep 2006, 07:51
OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
CPU-Target: AVR,ARM,x86(-64)
Wohnort: Dessau
Kontaktdaten:

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von Christian »

(@Christian: Aber wenn man keinen Typ Char benutzt geht's mit UTF8 natürlich ohne genaue Unicode-Kenntnisse, wenn auch mit schlechter Performance.)
Uiii, jetzt ists wieder die Perfomance, denn auf nem 286 oder beim verarbeiten von 500mb in einem String würde man durchaus einen Unterschied merken.
Für mich ist der Unicodeplan immernoch die beste Möglichkeit denn Speicher ist immernoch raraer als CPU Kapazität somit ist UTF-8 immernoch günstiger als WideString.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/

Socke
Lazarusforum e. V.
Beiträge: 3178
Registriert: Di 22. Jul 2008, 19:27
OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
CPU-Target: 32bit x86 armhf
Wohnort: Köln
Kontaktdaten:

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von Socke »

Christian hat geschrieben:Für mich ist der Unicodeplan immernoch die beste Möglichkeit denn Speicher ist immernoch raraer als CPU Kapazität somit ist UTF-8 immernoch günstiger als WideString.
UTF-8 = Unicode; WideString = UCS-2 = Unicode; oder versteh ich dich jetzt falsch?
wenn ich nur ein Zeichen vergleichen will, wäre doch Widestring schneller, da ich ja nur 2Byte mit 2Byte Vergleich; bei UTF-8 muss ich noch mehr prüfen (ob Multibytezeichen) und dann ggf. auch mehr vergleichen (theoretisch bis zu 9 Byte, praktisch bis zu 5 Byte)

Edit:
Christian hat geschrieben:Uiii, jetzt ists wieder die Perfomance, denn auf nem 286 oder beim verarbeiten von 500mb in einem String würde man durchaus einen Unterschied merken.
Wer liest bitte sehr einen 500MB String auf einmal in den Speicher?
MfG Socke
Zuletzt geändert von Socke am Di 6. Jan 2009, 22:42, insgesamt 2-mal geändert.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von theo »

Socke hat geschrieben: wenn ich nur ein Zeichen vergleichen will, wäre doch Widestring schneller, da ich ja nur 2Byte mit 2Byte Vergleich; bei UTF-8 muss ich noch mehr prüfen (ob Multibytezeichen) und dann ggf. auch mehr vergleichen (theoretisch bis zu 9 Byte, praktisch bis zu 5 Byte)
Kommt halt immer drauf an, was man machen muss.
Einen HTML Parser kann man beispielsweise unverändert von der ANSI auf die UTF-8 Version übernehmen.
Alle Steuerzeichen ( " = etc) sind im ASCII Bereich. Also braucht man tatsächlich nur diese Char vergleichen.
Ob dann im Content UTF-8 Sequenzen vorkommen, interessiert den Parser eigentlich nicht.

Sequenzen kann man mit PosEx suchen etc.

pluto
Lazarusforum e. V.
Beiträge: 7192
Registriert: So 19. Nov 2006, 12:06
OS, Lazarus, FPC: Linux Mint 19.3
CPU-Target: AMD
Wohnort: Oldenburg(Oldenburg)

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von pluto »

c:=UTF8Length(str);

macht keinen Sinn. Ein UTF-8 String sollte nicht in einem WideString sein.

Warum nicht ? So erhalte ich die richtige anzahl der Zeichen im String auch wenn Umlaute da sind. Sonst gibt es Fehler. Am besten lasse ich es erstmal so wie es ist. So geht es ja. Ich habe das Gefühl das wir aneinander vorbei reden.
s[5] nicht auf ein einzelnes Zeichen in deinem String zugreifen konntest,oder?
(bzw das die Length bei Umlauten falsch war)
RICHTIG. Wenn Umalaute/Sonderzeichen im String erhalten sind gibt es bei s[5] was falsches zurück wenn an der 5 Position ein Sonderzeichen ist nd Length gibt auch was Falsches zurück. Darum verwende ich im meinem Gesamten Projekt UTF8Length. Weil es dann so wie es für mich aussieht geht. Aber so wie es aussieht ist der zugrieff auf s[5] wenn es ein Sonderzeichen ist immer noch falsch.
Selbst dann wenn s als widestring definiert wurde oder muss das dann ein UTF8String sein um ganz sicher zu gehen ?

PS: Die heutige Preisfrage: Wie lange wird wohl dieser Thread noch laufen bis keiner mehr Antworten ? Was meint ihr :mrgreen:
Ich habe das Thema schon längst abgeschrieben, auch wenn ich noch auf eine bessere Lösung hoffe.
MFG
Michael Springwald

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von mschnell »

Socke hat geschrieben:D.h. unter Win32 (bei mir noch ohne) wird ein WideString nicht wirklich richtig angezeigt.
Die LCL-API ist UTF8String. Wenn ein Widestring angezeigt werden soll, muss man "Caption:=UTF8Encode(MyWideString);" schreiben, weil der FPC Widestring ebenso wenig automatisch richtig in UTF8String konvertiert wie umgekehrt. Das sollte eigentlich unabhängig vom Betriebssystem so sein.
-Michael

Benutzeravatar
theo
Beiträge: 10927
Registriert: Mo 11. Sep 2006, 19:01

Re: Erkennen ob das Zeichen ein UTF8 Zeichen ist

Beitrag von theo »

pluto hat geschrieben: Ich habe das Thema schon längst abgeschrieben, auch wenn ich noch auf eine bessere Lösung hoffe.
Pluto, liest du überhaupt was wir schreiben? Wir sind die ganze Zeit dabei, dir die "bessere Lösung" aufzuzeigen, aber du machst nicht mit.

Das was ich meinte mit

str:widestring;
begin
c:=UTF8Length(str);

ist nicht, dass das UTF8Length falsch ist, aber dass str vom Typ String (oder UTF8String) sein sollte. Sonst hast du einfach einen UTF-8 String auf DoubleByte aufgeblasen. Ausserdem weisst du dann gar nicht mehr, in welcher Form der String nun vorliegt.
Deshalb ist auch klar warum s[5] was falsches zurückgibt. Du solltest UTF8Decode machen. Das habe ich dir schon auf der ersten Seite gesagt....
Aber einfach einheitlich, also entweder du arbeitest mit UTF-8 und UTF8Length etc. oder mit UTF8Decode, WideString, Length etc.

Aber ich geb's jetzt auch auf.
Zuletzt geändert von theo am Di 6. Jan 2009, 23:30, insgesamt 1-mal geändert.

Antworten