AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein UTF8 Literale leserlich machen. Welche Unit / Funktion?
Thema durchsuchen
Ansicht
Themen-Optionen

UTF8 Literale leserlich machen. Welche Unit / Funktion?

Ein Thema von DieDolly · begonnen am 22. Jul 2019 · letzter Beitrag vom 25. Jul 2019
Antwort Antwort
Schokohase
(Gast)

n/a Beiträge
 
#1

AW: UTF8 Literale leserlich machen. Welche Unit / Funktion?

  Alt 23. Jul 2019, 07:20
Schlau? Weiß ich nicht ...
Augen offen? Ja auf jeden Fall ...

http://docwiki.embarcadero.com/Libra...TRegEx.Replace
Delphi-Quellcode:
class function Replace(const Input, Pattern, Replacement: string): string; overload; static;
class function Replace(const Input, Pattern: string; Evaluator: TMatchEvaluator): string; overload; static;
class function Replace(const Input, Pattern, Replacement: string; Options: TRegExOptions): string; overload; static;
class function Replace(const Input, Pattern: string; Evaluator: TMatchEvaluator; Options: TRegExOptions): string; overload; static;
Delphi-Quellcode:
type
  TMatchEvaluator = function(const Match: TMatch): string of object;
Eventuell macht das den Unterschied und wirkt auf andere schlau ... obwohl ich einfach nur die Augen offen habe
  Mit Zitat antworten Zitat
Rolf Frei

Registriert seit: 19. Jun 2006
656 Beiträge
 
Delphi 11 Alexandria
 
#2

AW: UTF8 Literale leserlich machen. Welche Unit / Funktion?

  Alt 24. Jul 2019, 16:58
mystring := UTF8Decode(#$C4+#$80+#$C4+#$86+'Hallo');

Das ergibt den String "ĀĆHallo"

Das Problem ist nun die "\x.." Zeichen in den entsprechenden 8-bit Zeichen Code umzuwandeln. Habe dazu schnell eine simple Routine geschrieben, die das macht. Diese müsste aber eventuell noch etwas überarbeitet werden, jenach dem was der Quellstring wirklich alles enthalten kann.

Delphi-Quellcode:
function DecodeCStyleString(const AStr: String): String;
var
  HexStr, ResultStr: RawByteString;
  i: Integer;
  IsCharLeadin: Boolean;
begin
  IsCharLeadin := False;
  i := 1;
  while i <= Length(AStr) do
  begin
    IsCharLeadin := AStr[i] = '\';
    if IsCharLeadin then
    begin
      IsCharLeadin := AStr[i+1] = 'x';
      if IsCharLeadin then
      begin
        inc(i, 2);
        HexStr := '$' + AStr[i] + AStr[i+1];
        ResultStr := ResultStr + AnsiChar(StrToInt(HexStr));

        inc(i);
      end
      else
        ResultStr := ResultStr + AnsiChar(AStr[i]);
    end
    else
      ResultStr := ResultStr + AnsiChar(AStr[i]);

    inc(i);
  end;

  Result := UTF8ToString(ResultStr);
end;

...

MyString := DecodeCStyleString('\xc4\x80\xc4\x86Hallo\xc4\x80');
// MyString ist nun "ĀĆHalloĀ"

Geändert von Rolf Frei (24. Jul 2019 um 17:20 Uhr)
  Mit Zitat antworten Zitat
Incocnito

Registriert seit: 28. Nov 2016
233 Beiträge
 
#3

AW: UTF8 Literale leserlich machen. Welche Unit / Funktion?

  Alt 25. Jul 2019, 08:08
Hi Zusammen,

ich würde nicht davon ausgehen, dass eine fremde Datenquelle mir saubere Daten schickt,
also habe ich noch zwei Sachen abgefangen:
1) Wenn nach dem "\x" nicht 2 Hex-Werte kommen, sondern nur einer und der String dann endet.
2) Wenn nach dem "\x" nicht 2 Hex-Werte kommen, sondern andere Zeichen und "StrToInt" schief gehen würde.
Delphi-Quellcode:
function DecodeCStyleString(const AStr: String): String;
var
  HexStr : RawByteString;
  ResultStr : RawByteString;
  i : Integer;
  iData : Integer; // Reicht Word?
begin
  i := Low(AStr);
  while (i <= High(AStr)) do
  begin
    if (AStr[i] = '\') then
    begin
      if ((i+3) < High(AStr)) and (AStr[i+1] = 'x') then
      begin
        Inc(i, 2);
        HexStr := '$' + AStr[i] + AStr[i+1];
        if (TryStrToInt(HexStr, iData)) then
        Begin
          ResultStr := ResultStr + AnsiChar(iData);

          Inc(i);
        end else
        begin
          ResultStr := ResultStr + '\x' + AStr[i];
        end;
      end else
      begin
        ResultStr := ResultStr + AnsiChar(AStr[i]);
      end;
    end else
    begin
      ResultStr := ResultStr + AnsiChar(AStr[i]);
    end;

    Inc(i);
  end;

  Result := UTF8ToString(ResultStr);
end;
Drei Dinge bleiben meiner Meinung nach noch zu klären:
1) Wenn der String mit "\xc" endet, könnte man gaaanz weit ausholen und da "\x0c" von machen,
aber will man das noch "abfangen"? Schließlich könnte man soetwas mitten im Text ja auch nicht erkennen!
2) Der Compiler spuckt noch Warnungen aus über Implizite Typ-Umwandlungen. Und Warnungen sind immer ein Hinweis darauf,
dass man etwas nicht richtig gemacht hat. Jetzt ist jemand gefragt, der sich mit Codepages und Zeichensätzen
auskennt. Man könnt das ganze zwar mit explizitem Typecase umgehen, aber das sagt dem Compiler ja
"ich weiß, was ich tue, mach einfach", aber ich weiß hier gerade nicht was ich tue, also seid ihr gefordert!
3) Wie im Kommentar schon zu sehen, aber irgendwie auch Teil von Punkt 2 "Reicht evtl. schon ein Word (2 Byte)
für das TryStrToInt?" Außerdem sagte mal jemand, dass "Integer" je nach EXE-Architektur den Standard-Zahltyp darstellt
("EXE-Architektur" ist sicher das falsche Wort, gemeint ist "Bei einem 64-Bit-Programm ist es ein 64-Bit Wert,
bei einem 16-Bit-Programm nur ein 16-Bit Wert"), aber dass kann jetzt auch von einer anderen
Programmiersprache kommen, oder ein totaler Irrläufer sein!

Außerdem gibt es vermutlich noch 1-2 Dinge zu verbessern, ohne gleich mit Pointern das ganze auf's Maximum zu optimieren.

Viel Spaß noch damit.

Liebe Grüße
Incocnito
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.212 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: UTF8 Literale leserlich machen. Welche Unit / Funktion?

  Alt 25. Jul 2019, 08:36
Warum macht ihr so etwas nicht mit regulären Ausdrücken 😐
  Mit Zitat antworten Zitat
Benutzerbild von Sherlock
Sherlock

Registriert seit: 10. Jan 2006
Ort: Offenbach
3.821 Beiträge
 
Delphi 12 Athens
 
#5

AW: UTF8 Literale leserlich machen. Welche Unit / Funktion?

  Alt 25. Jul 2019, 08:54
Also bei mir kommt so ein Krempel über SOAP rein. Das wird dann hiermit bereinigt und übersetzt:
Delphi-Quellcode:
uses System.JSON;

var myJSONValue:TJSONValue;


 // 'Gl\xC7\, cknerin' -> 'Glöcknerin'
          temp := StringReplace(temp, '\ ', ' ', []);
          temp := StringReplace(temp, '\n', ' ', []);
          temp := StringReplace(temp, '\, ', '', []);
          myJSONValue := TJSONObject.ParseJSONValue(StringReplace(temp.QuotedString('"'), '\x', '\u00',
            [rfReplaceAll]));
          if Assigned(myJSONValue) then
            temp := myJSONValue.ToString;
          temp := StringReplace(temp, '"', '', [rfReplaceAll]);
Und das wars dann schon. Ein paar sinnvolle trys und Frees bitte ergänzen.

Sherlock
Oliver
Geändert von Sherlock (Morgen um 16:78 Uhr) Grund: Weil ich es kann
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.757 Beiträge
 
Delphi 12 Athens
 
#6

AW: UTF8 Literale leserlich machen. Welche Unit / Funktion?

  Alt 25. Jul 2019, 09:36
So, ich möchte dann bitte auch nochmal (nur so wegen der Vielfalt):
Delphi-Quellcode:
uses
  System.SysUtils,
  System.Classes;

function DecodeCStyleString(const AStr: String): String;
const
  cLeadIn: TBytes = [$5C, $78]; // '\x'
var
  cnt: Integer;
  source: TBytes;
  target: TBytes;
  i: Integer;
begin
  source := TEncoding.UTF8.GetBytes(AStr);
  SetLength(target, Length(source)); // ausreichend Platz schaffen
  cnt := 0;
  i := 0;
  while (i < Length(source)) do
  begin
    if ((i + 3) < Length(source)) and
       CompareMem(@source[I], @cLeadIn[0], 2) and
       (HexToBin(source, I + 2, target, cnt, 1) = 1) then
    begin
      Inc(cnt);
      Inc(i, 4);
      Continue;
    end;
    target[cnt] := source[i];
    inc(cnt);
    Inc(i);
  end;
  Result := TEncoding.UTF8.GetString(target, 0, cnt);
end;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming

Geändert von Uwe Raabe (25. Jul 2019 um 09:59 Uhr) Grund: code fix
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#7

AW: UTF8 Literale leserlich machen. Welche Unit / Funktion?

  Alt 25. Jul 2019, 09:43
@UweRaabe

Ich weiß nicht warum, aber mit dem Code bekomme ich bei Delphi 10.3.2 nur Fehler
Code:
[dcc32 Fehler] Coding.dpr(14): E2029 ')' erwartet, aber ',' gefunden
[dcc32 Fehler] Coding.dpr(28): E2008 Inkompatible Typen
[dcc32 Fehler] Coding.dpr(29): E2015 Operator ist auf diesen Operandentyp nicht anwendbar
Zeile 14 ist die mit der cLeadIn: TBytes = ($5C, $78); // '\x' .
  Mit Zitat antworten Zitat
Benutzerbild von Codehunter
Codehunter

Registriert seit: 3. Jun 2003
Ort: Thüringen
2.291 Beiträge
 
Delphi 12 Athens
 
#8

AW: UTF8 Literale leserlich machen. Welche Unit / Funktion?

  Alt 25. Jul 2019, 09:45
Also was hier IMHO einer Erleuchtung im Wege steht ist der Mangel an zusätzlichen Informationen. Woher kommt der String, was für ein System, ggf. Quell- und Zielcodepages usw. Ein \xc4 und \x80 sagt ja erstmal nichts weiter aus als den Bytewert 196 und 128. Ohne Kenntnis der Codepage kommt man damit nicht weit.

128 lässt sich nach Windows-1251, Windows-1252 und ISO-8859-1 als "€" auflösen, 196 nach ISO-8859-1 als "Ä". Nach CP437 und CP850 kämen dann "├" und "Ç" raus. In Windows-1250 hättest du "Д" und "Ђ". Und so weiter.

Heißt: Um das richtig nach Unicode übersetzen zu können brauchst du die Information, welche 8-Bit-Codepage der Text hatte, BEVOR er in UTF-8 konvertiert wurde.
Ich mache grundsätzlich keine Screenshots. Schießen auf Bildschirme gibt nämlich hässliche Pixelfehler und schadet der Gesundheit vom Kollegen gegenüber. I und E zu vertauschen hätte den selben negativen Effekt, würde aber eher dem Betriebsklima schaden
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 20:28 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz