Text Konvertierung

  • Hi,

    ich hoffe ihr könnt mir weiter helfen, eventuell übersehe ich die Lösung auch.

    Ich bekomme Text aus einer API Abfrage, leider sind dort die entsprechenden Sonderzeichen falsch dargestellt. Also vermutlich ein Codierungsproblem.

    Nun finde ich aktuell keinen Weg diese richtig darzustellen.

    Beispiel (oben IST | unten SOLL):

    é,ü,ö,Ã,ä,è

    é,ü,ö,ß,ä,è

    Jemand eine Idee welche Konvertirung das wäre und wie ich das korrigiert bekomme?

    Ein einfaches Stringreplace funktioniert leider nicht :(

    Nachdem ich die Codierung in Autoit auf UTF8 geändert habe, würde das Stringreplace funktionieren, jedoch sehe ich das aktuell nicht als Lösung an, da zu viele Sonderzeichen existieren wenn man international arbeitet.

    Einmal editiert, zuletzt von Moombas (5. Januar 2023 um 14:01)

  • Wenn der Input-String die Soll-Daten enthält und diese per UTF-8 kodiert sind.

    Dann erhält man dein obiges Ergebnis, wenn man die Daten stattdessen fälschlicherweise als ASCII/ANSI interpretiert:

    AutoIt
    $sInput = "é,ü,ö,ß,ä,è"
    
    ; String als UTF-8 kodiert in Variable speichern:
    $bQuelle = StringToBinary($sInput, 4)
    
    ; String als ASCII interpretiert einlesen:
    $sOutput = BinaryToString($bQuelle, 1)
    
    ; Ausgabe
    MsgBox(0,"", $sOutput)


    Um zu schauen wie man es beheben kann müsste man erstmal wissen, woher die Daten stammen und wie sie eingelesen werden.
    Im Falle von z.B. InetRead würde man einfach ein BinaryToString(..., 4) drumherum packen.
    Aber wie gesagt - muss man schauen wie es konkret gemacht wird.

  • Hi Moombas ,

    hast du das Ergebnis der API Abfrage als Datei vorliegen (also als JSON response) oder ist es direkt in einer Variable gespeichert?
    Warum ich frage ist, wenn du eine Datei hast, dann Datei kannst du diese doch mit entsprechendem Encoding öffnen und neu speichern.
    Dann sollten die Sonderzeichen korrekt dargestellt werden.

    Kannst du den JSON response unverfälscht mal zu Verfügung stellen?

    Viele Grüße
    Sven

  • Hi AspirinJunkie ,

    meinst du nicht gerade anders herum in deinem code snippet oben? Also so:

    AutoIt
    $sInput = "é,ü,ö,ß,ä,è"
    
    ; String als ASCII kodiert in Variable speichern:
    $bQuelle = StringToBinary($sInput, 1)
    
    ; String als UTF-8 interpretiert einlesen:
    $sOutput = BinaryToString($bQuelle, 4)
    
    ; Ausgabe
    MsgBox(0,"", $sOutput)

    Oder stehe ich gerade auf dem Schlauch?
    Abgesehen davon: Cool, Danke! Habe das in der Vergangenheit (wenn ich's mal gebraucht habe), also immer zu umständlich gemacht 😅 .

    Viele Grüße
    Sven

  • 💡 Und wieder fehlt mir der "Like" button [...].

    Alles klar und Danke dir AspirinJunkie 👍 .

    Viele Grüße
    Sven

  • Wenn der Text aus der API Abfrage immer "gleich falsch" ist, und davon gehe ich aus, sonst hätte Moombas das ja entsprechend angemerkt, dann würde ich einfach den 3 Zeiler von AspirinJunkie bzw. SOLVE-SMART verwenden - damit ist das Problem fix vom Tisch. Gedanken über warum das ein so codiert ist und nicht anders - mache ich mir schon lange nicht mehr. Ich kämpfe seit Jahren mit Daten in den unmöglichsten "Formaten". Und habe für mich beschlossen alles in UTF-8. Also verwandle ich brav hin und her - und habe letzlich meine Ruhe :)

    LG

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Also danke schon vielmals, ich versuche mal das stepbystep zu beantworten:

    #2: Die Daten Stammen aus einem Cloud Verwaltungstool, dort ist leider nicht angegeben in welcher Codierung die Daten zurück kommen. Ich arbeite bei mir in Autoit immer mit einer anderen Codierung, da ich das für ein weiterführendes Tool brauche (99% meiner Scripte versorgen dieses, daher per Standard auf anderer Codierung eingestellt).

    Mit StringtoBinary habe ich auch shcon gespielt, da ich aber die Codierung nicht wusste habe ich es verworfen. Danke dafür!

    #3: Ich benutze das direkt aus der Variable aber speichere mir das Originale immer nebenbei weg, damit ich, falls Fehler auftreten etwas direkt zum Vergleichen habe. In Notepad++ habe ich die Codierung auf ANSI geändert und das Problem blieb bestehen (nur die falschen Zeichen haben sich geändert).

    Da es sich hierbei um Firmeninterne Daten handelt kann ich diese leider nicht zur Verfügung stellen.

    #7: Jepp, habe es mit der "gedrehten" Variante getestet und bis auf das 'ß' (das ich nun noch gesondert per Stringreplace ersetze) funktioniert es einwandfrei.

    AutoIt
    Func CorrectName($Name)
    Local $Return = StringToBinary($Name, 1)
        $Return = BinaryToString($Return, 4)
        $Return = StringReplace($Return, '�?', 'ß')
        Return $Return
    EndFunc
  • und bis auf das 'ß' (das ich nun noch gesondert per Stringreplace ersetze) funktioniert es einwandfrei.

    Das hängt damit zusammen, dass das ß nicht im ANSI-Satz existert.

    8-Bit-Kodierungen mit ß wären stattessen die ISO 8859-15, cp1252 oder Macintosh Roman.

    Kurz: Du versuchst das Problem einen Schritt später zu lösen und musst daher noch mehr Umstände machen als eigentlich nötig.

    Ich frage noch einmal: Wie kommen die Daten in AutoIt an.
    Liest du die aus einer Datei, bekommst du sie per InetRead oder oder oder?

    An dieser Stelle muss bereits mit der richtigen Kodierung angesetzt werden und nicht erst hinterher in eine 2. und 3. Kodierung hin und her kodiert werden.

    Offensichtlich kommt in deinem Originalstring ein ß vor - also liegt dieser schonmal definitiv nicht in ASCII/ANSI vor.
    Eine Zwischenkodierung nach ANSI führt dann zu eben solchen Problemen.

    Also nochmal ganz konkret: Auf welche Art landen die Daten als String in AutoIt?

  • Hmmm

    ich bin nicht ganz mit AspirinJunkie einer Meinung. Oftmals kann man die Quelle nicht verändern - ist eben so!

    Moombas Deinen Versuch mit Notepad ++ kann ich nachvollziehen aber mit mehr Erfolg.

    Stell Kodierung auf UDF 8 gib Deine Zeile 1 ein,

    Konvertiere Deine Zeile 1 nun in Notepad++ nach Ansi

    gehe nun her und stelle die Ansicht auf UDF-8 um ----> und der String ist konvertiert mit Ausnahme des scharfen ß.

    Was ich nicht verstehe ist, dass der Code bei Dir kein scharfes ß liefert. Bei mir macht er das - anyway ist ja kein Problem wenn das so ist --> strinreplace fürs ß

    Eigentlich sollte Dein Problem doch damit gelöst sein? Oder übersehe ich da was?

    LG

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Oftmals kann man die Quelle nicht verändern - ist eben so!

    Die Quelle soll nirgends verändert werden.
    Sie soll nur von Anfang an exakt so behandelt werden wie sie tatsächlich beschaffen ist.
    Der derzeitige Weg von Moombas macht aber eben genau das nicht.

    Aktuell erhält er Daten die eindeutig nicht in ASCII/ANSI kodiert sind (mutmaßlich liegen die Daten als UTF-8 kodiert vor), und konvertiert sie in ANSI um sie anschließend nach UTF-8 zu kodieren.
    Dabei gehen zwangsläufig Zeichen flöten die nicht Bestandteil des ANSI-Zeichensatzes sind (wie eben das ß).

    Das noch fehlende Puzzlestück ist hier am Anfang zu suchen: Wie genau kommen die Daten in AutoIt rein?
    Dort muss die korrekte Kodierung angesetzt werden und nicht irgendwann später durch wildes hin und her kodieren.
    Die Originaldaten werden dabei zu keiner Zeit verändert.

  • AspirinJunkie

    da habe ich mich wohl unklar ausgedrückt. Sorry. Natürlich sollte man die Daten von Anfang an richtig codiert einlesen. Aber wenn das, warum auch immer, nicht geht dann eben umcodieren. Das war das was ich mit Quelle nicht verändern meinte.

    Da könnten noch mehr Zeichen fehlen - da hast Du recht. Da sollten wir also hoffen dass der TE eigenen Input erzeugen kann...sich also Nachrichten mit allen möglichen Sonderzeichen selbst zu senden und dann die Ersetzungen zu hinterlegen. Gibt ein paar Zeilen Code aber nix aufwendiges

    Mir ist klar das ist wiedermal extrem pragmatisch aber warum nicht?

    LG

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Hi, bitte nicht streiten ;)

    Die Daten kommen wie gesagt aus einer API Schnittstelle, die ich über AutoIt per winhttp request anspreche.

    Leider ist in der Doku zur API nicht hinterlegt welche Codierung zurück kommt aber ich vemrute das hier 2 Probleme aufeinander treffen:

    1. Die Text-Codierung (ich vermute UTF-8, da die CSV die ich dort einlesen kann nur UTF-8 akzeptieren)

    2. HTML-Probleme mit Sonderzeichen

    Das ist aber nur eine Vermutung. Im Original bekomme ich z.B. das hier: Hammersbacher StraÃe, wenn ich die Daten per FileWriteFromArray speicher, das ja als UTF 8 speichert.

    Grundsätzlich würde es halt mit dem oben genannten "workaround" gehen, wobei ich immer natürlich die 100% Lösung bevorzugen würde.

  • Naja, nur gut, dass nicht nur ich dieses "Problem" habe!

    Die Quelle soll nirgends verändert werden.
    Sie soll nur von Anfang an exakt so behandelt werden wie sie tatsächlich beschaffen ist.

    Und genau hier liegt der Hase im Pfeffer! Imho ist es nicht die Sache der Anwender, sich für die DARSTELLUNG der Daten die passende Kodierung heraussuchen zu müssen! So etwas gehört in eine Dokumentation!

    Mein täglich Brot als "Kunde" war u.a. die Abfrage einer Terabyte-großen ERP-Software-Datenbank mit mehreren tausend Tabellen, das ERP-Programm wurde zu allem Überfluss von einem international agierenden Team erstellt.

    So lange man mit der GUI dieses Programms zu tun hatte, war "meistens" alles in Ordnung, d.h. die deutschen Sonderzeichen wurden auch entsprechend dargestellt.

    Aber schon beim Ausdruck der Daten kam es "manchmal" bei deutschen Sonderzeichen zu Problemen. Hinweise auf "Probleme" in der Kodierung der Tabellen bzw. deren Abfrageergebnisse wurden seitens Programmhersteller "abgewatscht", viel zu kompliziert, uber Jahre gewachsenes Programm mit internationalem Hintergrund, blabla...

    Für die Bereitstellung interner Daten(zusammenhänge) hatte ich mir dann mehrere Tools in VBA geschrieben. Dabei ist mir aufgefallen, dass je nach Gusto des DB-Programmierers und dessen globalen Standort, "willkürlich" eine Kodierung beim Anlegen einer Tabelle gewählt wurde! Was in der GUI natürlich völlig problemlos ist, da der GUI-Programmierer mit seinem Datenbankspezi im gleichen Raum sitzt und ALLE Spezifikationen einsehen und somit in seiner Darstellung anpassen kann. Die "Erweiterung" auf Webinterfaces mit HTML und entsprechender Abfragen macht das Chaos perfekt! Übergabe von Daten an Programme anderer Hersteller, durch AutoIt automatisiert? Viel Spass!

    Als ANWENDER hast du bis auf rudimentäre Dokumentation NICHTS (außer Sodbrennen)!

    Ich also quer über den Wust an Daten fleißig Tabellen verknüpft und Abfragen gestaltet, die Daten dann entweder per VBA in Officeprodukten dargestellt, auf diverse Druckmedien (Papier, Etiketten, Laserbeschrifter uswusf.) ausgegeben und mich jedes Mal über die Mehrarbeit gefreut, wenn deutsche Sonderzeichen nicht "richtig" behandelt wurden.

    Zu allem Überfluss hatte ich dann den gesamten Ablauf auf Barcodes umgestellt, was wiederum die Probleme vervielfacht hat. Ja, auch Scanner, die in meinem Fall mit mehreren Softwareprodukten unterschiedlichster Hersteller zusammenarbeiten müssen/sollen, habe unterschiedlichste Einstellungen in der Kodierung!

    Bring mal mehrere Software- und Hardwarehersteller unter einen Hut, die ALLE eine WILLKÜRLICHE Kodierung verwenden!!!

    Wenn man sich mit dem Thema intensiv beschäftigen muss, dann tun sich einem ABGRÜNDE auf!

    Da werden von einem Maschinenhersteller Barcode-Handscanner für eine Maschine für 1500 Euro per Stück "konfektioniert" angeboten, obwohl der 50€-Scanner das ebenso kann! Warum?! Nicht etwa, weil der Scanner so "toll" ist, sondern weil er im Auslieferungszustand des Scanner(!)herstellers auf eine bestimmte Kodierung eingestellt ist....Scanner defekt, neuen bestellt, auspacken, anschließen, läuft.

    50€-Scanner bestellt, ausgepackt, angeschlossen, KODIERUNG LT. HANDBUCH GEÄNDERT/AUF MASCHINE ANGEPASST, angeschlossen, läuft.

    Etikettendrucker das gleiche Spiel!

    Ich behaupte mal, 99,9 % aller "Anwender" sind nicht in der Lage, den "Fehler" einer abweichenden Kodierung zu erkennen, die "sehen" nur "falsche" Zeichen! Wenn sie überhaupt irgendetwas sehen, meistens "funktioniert" nur etwas einfach nicht! Respektive Maschinen, die nicht funktionieren (können) weil "falsche" Zeichen übermittelt werden. Und kaum eine Software/Hardware kann "einfach" abgepasst/umgestellt werden!

    Ich habe mich diesem Procedere angepasst! Ich habe mir in diversen Programmiersprachen (Test-)Filter und Module geschrieben, die dieses "Manko" beheben. Ich schieße mit einer speziell dafür angelegten Testabfrage per SQL auf eine Datenbank (aka API auf ein Webinterface), deren Kodierung ist mir VÖLLIG wurscht, das Ergebnis wird in eine Tabelle geschrieben und die "richtige" Kodierung (bzw. mein Filter) für die Weiterarbeit ausgewählt. Das funktioniert bei allen Abfragen! Auch bei Hardware (Barcodescannern), die dann entsprechend umprogrammiert werden....

    Btw, Regexe zum "erkennen" invalider Kodierungen sind mein Freund....

    Und ja, ich bin KEIN Programmierer! Ich habe 90% meiner Arbeit mit ganz anderen Dingen zu tun....da fragt sich irgendwann der Normalsterbliche, was gestandene "Programmierer" zu diesem Thema sagen?! Meine Erfahrung nach etlichen Jahrzehnten.....die sagen NICHTS dazu, sind meistens völlig Hilflos und verweisen auf den Support des "anderen" Software/Hardwareherstellers! Industrie 4.0 anyone?!

  • wobei ich immer natürlich die 100% Lösung bevorzugen würde.

    Na dann versuchen wir es doch mal.

    Ändere mal die eine folgende Zeile entsprechend:

    $oHTTP.SetRequestHeader('Content-Type', 'application/json;charset=' & $charset)

    und für $charset mal "utf-8" eintragen und mal "US-ASCII" und da mal schauen ob das einen Unterschied macht.

    Im schlimmsten Fall bekommt winhttprequests die falsche Kodierung vom Server gemeldet als die Daten tatsächlich haben und bastelt dann doch alles zwangsweise in UTF-8.

    Das könnte das Problem erklären.

    Eine Alternative wäre über InetGet zu gehen.

    Ich weiß aber nicht ob es einen wichtigen Grund gibt, warum du jetzt explizit das winhttprequests-Objekt verwendest.

    Für mich sieht es nicht so aus, als würdest du POST-Parameter mitschicken.

    Eine (wie bei dir verwendete) Basic-Authentifizierung sollte beispielsweise auch folgendermaßen mit InetRead gehen:

    AutoIt
    $sTarget = "authenticationtest.com"
    $sRequest = "/HTTPAuth/"
    $sUser = "user"
    $sPassword = "pass"
    
    $sURL = StringFormat("https://%s:%s@%s%s", $sUser, $sPassword, $sTarget, $sRequest)
    
    $sResponse = BinaryToString(InetRead($sURL), 4)
    ConsoleWrite($sResponse & @CRLF)

    Will sagen: Wenn du auf InetRead ausweichen kannst, hättest du mehr Kontrolle über die Kodierung (über den 2. Parameter von BinaryToString).
    Aber wie gesagt nur wenn es keine anderen zwingenden Gründe für winhttprequest gibt.

  • Ich nutze diese Funktion für GET, PUT und POST requests, daher muss ich dabei bleiben, wenn auch in diesem Fall es wirklich nur ein Get request ist..

    Ich habe deinen Vorschlag mit dem Charset getestet aber das Ergebnis ändert sich (leider) nicht.

  • Zu Andy s Beitrag ist nichts aber auch gar nichts hinzuzufügen. Dem ist so! Mir geht es in einer, zwar nicht so mächtigen, aber eben auch ERP usw. tagtäglich genauso. Jeder codiert wie er lustig ist! Und (ich bin auch keine Hauptberuflicher) Programierer tun immer so als hätten Sie die Weisheit mit dem Löffel....

    Anyway. Ich für mich habe beschlossen das nicht an der Quelle sondern in Autoit zu lösen. Stringreplace oder ähnliches und gut ist es. Taucht mal wieder eine neues Sonderzeichen auf .... eine Abfrage mehr. Wobei das, wenn genau hinschaut nicht vorkommt. Wir haben mal unsere deutschen Sonderzeichen, ev. Französische, und ja wer mit osteuropa zu tun hat.... aber das kann ich nicht bewerten - kommt bei mir nicht vor.

    Pack Deine Daten alle in einen String, füge ein von Dir "definiertes" Trennzeichen hinzu und Filtere auf das was ersetzt werden muss, wegen mir auch nach ganzen Begriffen. Austauschen fertig.

    LG

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Moombas

    geradeheraus gefragt, was spricht gegen Die Lösung mit der Konvertierung von #2/#3 und dann, sofern das ß übrigbleibt ein stringreplace?

    LG

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • Ich nutze ja aktuell die Lösung mit dem BinarytoString etc. und die funktioniert auch.

    Wenn es jedoch auch eine Lösung gibt, die das Problem "an der Wurzel" packt, würde ich diese halt bevorzugen aber ja, generell tut sie's.