Entwickler-Ecke

Sonstiges (Delphi) - UTF8, Html und Strings


Gausi - Sa 26.07.08 13:55
Titel: UTF8, Html und Strings
Ich hab da ein kleines Problem, wo mir bestimmt jemand eine bessere Lösung sagen kann als meine, die auf x Runden StringReplace basiert...

Ich habe verschiedene Strings, die mal UTF-8 kodiert sind, und mal so "komisch mit html-Zeugs" drin. Wann was auftritt, ist erstmal nicht bekannt, aber ich glaube auch, dass das egal ist. :gruebel: Die Html-Strings z.B. sehen so aus:
Zitat:
dann wird die Bühne zur Welt.

Hier ist also das & in ü für ein ü mit & maskiert - man müsste als zweimal Stringreplace drüberlaufen lassen. Da einige Texte UTF-8-kodiert sind, z.B.
Zitat:
Mein Verhältnis zu Behörden war nicht immer ungetrübt
, müsste das Umbauen des Srings dann so gehen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
MeinWideString := HtmlWeg(UTF8Decode(MeinString));

function HtmlWeg(s: WideString): WideString;
begin
  result := WideStringReplace(s, '&''&');
  result := WideStringReplace(result, 'ü''ü');
  // usw.. die anderen auch ersetzen

Was mich daran stört, ist das vielfache StringReplace. Geht das auch einfacher?


BenBE - Sa 26.07.08 15:40

Wu Mamber zum Suchen jeglicher zu ersetzender Vorkommen und dann anhand der sortierten Vorkommen den String schnell selber neu aufbauen.


Gausi - Sa 26.07.08 17:21
Titel: Re: UTF8, Html und Strings
user profile iconGausi hat folgendes geschrieben:
Geht das auch einfacher?


user profile iconBenBE hat folgendes geschrieben:
Wu Mamber zum Suchen jeglicher zu ersetzender Vorkommen und dann anhand der sortierten Vorkommen den String schnell selber neu aufbauen.


Genau sowas wollte ich nicht hören. :lol: Ich glaube auch nicht, dass WuManber hier unbedingt das wahre ist, weil die zu suchenden Strings recht kurz sind. Ich dachte halt an irgendeine schicke Funktion, die das elegant regelt. Sowas braucht man doch eigentlich öfter, oder nicht?


BenBE - Sa 26.07.08 17:40

Zumindest nicht bei Delphi. Bei PHP macht das string_replace in der Variante string_repalce(array('s1', 's2', ...), array(1, 2, 3), $subject) Was die da aber intern nutzen, weiß ich jetzt nicht auf Anhieb.

Du könntest aber u.U. auch nen Suchbaum mit Ansätzen von Boyer-Moore verwenden, wobei jedes Blatt das Ziel-Ersetzungszeichen beinhaltet.


Bernhard Geyer - Sa 26.07.08 18:27

Woher kommen die Daten? Kannst du es nicht durch einen richtigen HTML-Parser (z.B. TWebBrowser) aufbereiten lassen?


Gausi - Sa 26.07.08 19:11

Es geht mir nicht so sehr um die Anzeige - die Daten werden hinterher in einem TMemo (bzw. TntMemo) angezeigt, von daher bringt der TWebbrowser eher weniger, denke ich. Die Daten sind Songtexte, die ich über Lyricwiki.org [http://lyricwiki.org/LyricWiki:REST] bekomme. Und die sind nicht immer gleich schön kodiert. Mein Ansatz funktioniert soweit ganz gut - bis auf einige Anführungsstriche, da geht noch irgendwas schief. Von der Geschwindigkeit her dürfte auch das Speichern der Texte im ID3Tag der Dateien auch den Löwenanteil ausmachen.

Nur ich neige dazu, bei einigen Problemen schonmal ein paar Umwege zu gehen, und hier schien mir das so. Und evtl. könnte ich den Teil in die Library stellen - denn das funktioniert deutlich schneller (so ca. 1-4 Songs/sek) und zuverlässiger als das hier [http://www.delphi-forum.de/viewtopic.php?p=510787#510787]. ;-)


Gausi - Do 18.09.08 16:17

Das Problem hat sich jetzt erstmal erledigt - aber wie mach ich das andersrum? Ich will dafür kein neues Topic aufmachen, denn der Titel wär praktisch der gleiche. ;-)

Also. Ich habe jetzt ein paar (Wide-)Strings, deren Inhalt ich in eine HTML-Seite packen möchte. Rahmen drumherum ist klar - aber wie pack ich einen Widestring am besten da rein? UTF8Encode drüberlaufen lassen (Charset des Dokuments dann auf utf-8 stellen) und dann die übrig gebliebenen "bösen" Zeichen wie < > / & und evtl. ein paar mehr gesondert escapen (z.B. als &amp;)? Oder wie macht man das?


Gausi - Mo 22.09.08 19:21

Ich probier hier weiter rum... ich habe jetzt sowas erfolgreich getestet:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function EscapeHTMLChars(s: WideString): WideString;
begin
    result := Tnt_WideStringReplace(s, '&''&', [rfReplaceAll]);
    result := Tnt_WideStringReplace(result, '<''<', [rfReplaceAll]);
    result := Tnt_WideStringReplace(result, '>''>', [rfReplaceAll]);
    result := Tnt_WideStringReplace(result, '"''"', [rfReplaceAll]);
end;

//...

PartofHtmlCode := UTF8EnCode(EscapeHTMLChars(MyText));

// write PartofHTMLCode in Stream,
// verschicke Stream per IdHttpServer ...


Und das klappt scheinbar. D.h. Wenn MyText ein Stück HTML-Code enthält, dann wird dieser wie gewünscht so ausgegeben und nicht vom Browser geparsed.

Frage: reicht das? Oder mus ich mehr Zeichen vorher escapen? Charset des Dokuments ist UTF-8.


BenBE - Mo 22.09.08 21:58

user profile iconGausi hat folgendes geschrieben:
Ich probier hier weiter rum... ich habe jetzt sowas erfolgreich getestet:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
function EscapeHTMLChars(s: WideString): WideString;
begin
    result := Tnt_WideStringReplace(s, '&''&', [rfReplaceAll]);
    result := Tnt_WideStringReplace(result, '<''<', [rfReplaceAll]);
    result := Tnt_WideStringReplace(result, '>''>', [rfReplaceAll]);
    result := Tnt_WideStringReplace(result, '"''"', [rfReplaceAll]);
end;

//...

PartofHtmlCode := UTF8EnCode(EscapeHTMLChars(MyText));

// write PartofHTMLCode in Stream,
// verschicke Stream per IdHttpServer ...

Sollte man nicht erst UTF8-Encoden UND DANN erst escapen???

user profile iconGausi hat folgendes geschrieben:
Und das klappt scheinbar. D.h. Wenn MyText ein Stück HTML-Code enthält, dann wird dieser wie gewünscht so ausgegeben und nicht vom Browser geparsed.

Frage: reicht das? Oder mus ich mehr Zeichen vorher escapen? Charset des Dokuments ist UTF-8.

hmmm, wenn ich htmlspecialchars von PHP richtig im Kopf hab, nutzt die auch nur diese 4 Ersetzungen ...


GTA-Place - Mo 22.09.08 23:29

Ein Zeichen fehlt noch: der Apostroph ' mit &#039;


Gausi - Di 23.09.08 08:04

user profile iconBenBE hat folgendes geschrieben:
Sollte man nicht erst UTF8-Encoden UND DANN erst escapen???
Wie wird das Dokument denn von einem Browser verarbeitet? Wird zuerst das Dokument als ganzes als UTF-8-Datei behandelt, dekodiert und dann als HTML-Dokument geparsed oder wird zuerst HTML geparsed und der Textinhalt der einzelnen Elemente einzeln als UTF-8-kodierter Text interpretiert? Ich bin von ersterem ausgegangen. :gruebel: (Aber ich merke grade: Das macht ja eigentlich weniger Sinn.)

@Apostroph: Sicher? Klar, die Sache mit der SB letztens habe ich mitbekommen, aber bei mir arbeitet im Hintergrund weder PHP noch eine Datenbank, die man mit sowas kaputt kriegen könnte.