Forum: PC-Programmierung [VB.net] UTF String ("\u00f6") in ASCII Char "ö" wandeln


von UTFler (Gast)


Lesenswert?

Hallo Leute,

Ich habe das Problem, dass wenn ich über eine RestAPI Daten auslese,
z.Bsp. den Namen "Sepp P\u00f6lzler" auslese.
Dieser Name wird komplett als String geliefert.
Der Name wird anschliesend nach "ASCII konvertiert".

Hierfür verwende ich folgende "lookup" liste:
1
NewString = NewString.Replace("\u00e4", "ä")
2
NewString = NewString.Replace("\u00e8", "è")
3
NewString = NewString.Replace("\u00e9", "é")
4
NewString = NewString.Replace("\u00ed", "í")
5
NewString = NewString.Replace("\u00f1", "ñ")
6
NewString = NewString.Replace("\u00fc", "ü")
7
NewString = NewString.Replace("\u00f6", "ö")
8
NewString = NewString.Replace("\u003c", "<")

Danach ist der String wieder "Sepp Pölzler"

Habe mir schon mal das system.text.encoding angesehen und auch bei MS 
folgenden Code gefunden:
(Vielleicht braucht den mal jemand)
1
Public Function UnicodeToAscii(ByVal unicodeString As String) As String
2
Dim ascii As Encoding = Encoding.ASCII
3
Dim unicode As Encoding = Encoding.UTF8
4
Dim unicodeBytes As Byte() = unicode.GetBytes(unicodeString)
5
Dim asciiBytes As Byte() = Encoding.Convert(unicode, ascii, unicodeBytes)
6
Dim asciiChars(ascii.GetCharCount(asciiBytes, 0, asciiBytes.Length) - 1) As Char
7
ascii.GetChars(asciiBytes, 0, asciiBytes.Length, asciiChars, 0)
8
Dim asciiString As New String(asciiChars)
9
Return asciiString
10
End Function

Leider hilft der mir nicht weiter, weil er "\u00f6" in "\u00f6" 
konvertiert.
Ich brauche aber etwas, das aus dem STRING "\u00f6" das CHAR "ö" 
erstellt.

Kann mir da wer weiter helfen?

von MaWin (Gast)


Lesenswert?

Das ö ist kein ASCII char. (Das A steht für American. Die haben keine 
ös)
Vermutlich ist dein encoding Latin-1 statt ASCII.

von UTFler (Gast)


Lesenswert?

Latin-1
Ähhhm. Ja. Hast Recht.

von 🐧 DPA 🐧 (Gast)


Lesenswert?

UTFler schrieb:
> Danach ist der String wieder "Sepp Pölzler"

Der String ist immer "Sepp Pölzler", nur in anderer Codierung. Nur 
Unicode ist universal. Behalte also die Unicode/UTF-* Codierung immer 
bei, solange möglich. UTF-8 ist die beste Encoding, immer noch lesbar in 
alten Programme, in den meisten Fällen byteweise behandelbar wie normale 
ASCII / byte Strings, keine Versuchung, eine Unit als Zeichen oder gar 
Glyph zu missinterpretieren, etc. Wobei .net / MS Zeugs ist aus 
historischen gründen leider nativ ein quasi UTF-16. Sollte aber keine 
grosse rolle Spielen. Der String Typ in .net sollte so oder so 
Unicode/quasi UTF-16 enthalten, aber in VB ist das historisch wohl nicht 
immer so. Deine ursprünglichen Daten scheinen aber ja schon richtig in 
Unicode zu sein, also lass die so wie sie sind.

Lange Rede kurzer Sinn, konvertiere nicht den Unicode String nach Ascii. 
Stelle stattdessen sicher, dass du überall Unicode, und die 
Unicodevarianten der diversen Funktionen verwendest. Bei WinAPI sind das 
die Funktionen, die mit W statt mit A enden. C# macht das wohl 
automatisch, aber VB nicht. Falls du in die Console was ausgibst, musst 
du da eventuell auch noch was bei der Codierung einstellen. Aber den 
String kann man fast immer so lassen. Einfach den Rest des Programms 
korrigieren.

von UTFler (Gast)


Lesenswert?

Das Problem ist, das es dann an ein Buchhaltungsprogramm übergeben wird.
Mit meiner Konvertierung nach "ö" klappt das supper.
Aber "u00f6" im Namen kommt nicht gut.
Ich MUSS also nach Latin konvertieren.

von 🐧 DPA 🐧 (Gast)


Lesenswert?

Ok, da lässt sich dann wohl tatsächlich nichts dagegen machen.

von UTFler (Gast)


Lesenswert?


von Schlaumaier (Gast)


Lesenswert?

UTFler schrieb:
> Ich habe das Problem, dass wenn ich über eine RestAPI Daten auslese,

Dann ist es schon viel zu spät.

Du musst MS sagen das wie es die Daten lesen soll bzw. schreiben.

Ansonsten schaue dir mal da an :
-----

Encoding.Convert-Methode (Encoding, Encoding,Byte(), Int32, Int32)

Public Shared Function Convert ( _
      srcEncoding As Encoding, _
      dstEncoding As Encoding, _
      bytes As Byte(), _
      index As Integer, _
      count As Integer _
  ) As Byte()


Konvertiert einen Bereich von Bytes in einem Bytearray aus einer 
Codierung in eine andere.
------
Wenn das nicht klappt hilft leider auch nur die von Hand Methode.

Ist aber auch nicht wirklich schlimm.

Ich muss die in 2 meiner Prg. auch verwenden. Einfach den Replace über 
eine Funktion aufrufen.  Ich habe in meiner privaten DLL inzwischen 4 
Convert-Methoden drin. Eine davon ist so schlimmer das ich die 
Umwandlung sogar mit einer eigenen Replace-Funktion machen muss.

Die MS Replace-Methode ist nämlich manchmal "zickig". Besonders wenn da 
spezielle Zeichen drin sind.  Manchmal hilft der Compare - Parameter. 
Aber auch dann nicht immer.

von Schlaumaier (Gast)


Lesenswert?

Nachtrag :

Solltest du zufällig nachkomma-Stellen dabei haben, achte immer darauf 
das der auch die Deutsche punkt/Komma regel beachtet, sonst fehlen dir 
plötzlich die Nachkomma werte.

Auch hast du Probleme beim Convertieren wenn im Text Steuerzeichen sind. 
Dann steigt Replace gern aus.

von 🐧 DPA 🐧 (Gast)


Lesenswert?

Ich kann kein VB, aber ich hab mir mit der .net API Doku und etwas 
probieren mal schnell was zusammengeschustert:
1
Imports Encoding = System.Text.Encoding
2
3
Module VBModule
4
    Sub Main()
5
        Dim unicode_message As String = "Hèllö Wôrld"
6
        Dim ISO_8859_1 As Encoding = Encoding.GetEncoding("ISO-8859-1")
7
        Dim ascii_bytes As Byte() = ISO_8859_1.GetBytes(unicode_message)
8
        Console.WriteLine(unicode_message)
9
        Console.WriteLine(BitConverter.ToString(ascii_bytes))
10
    End Sub
11
End Module
https://onlinegdb.com/DaRlmxh3R

Für Encoding.Convert sehe ich hier keinen bedarf. Das GetBytes ist ja 
sowieso für eine bestimmte Encoding / konvertiert bereits.

von Schlaumaier (Gast)


Lesenswert?

🐧 DPA 🐧 schrieb:
> Ich kann kein VB, aber ich hab mir mit der .net API Doku und etwas
> probieren mal schnell was zusammengeschustert:

Ist das selbe.

VB selbst ist ein ganz kleiner Teil vom Kuchen. Die von dir gewählte 
Sache gehört NICHT zu VB sondern zu den MIT von VB genutzten 
NET-Framwork 4.0.

Grundsätzlich bedeutet das : VB + VC sind von der Syntax und von Aufbau 
unterschiedlich. ABER die meinsten Aufrufe sind eh welche des Framework, 
die der Compiler in das passende System interegiert.

Einfach gesagt, schau dich immer im Framework um. Da ist x-mal mehr drin 
als in deiner Programmiersprache. Und du musst bei VB(.net) + VC(.net) 
eh immer das Framework unter Projekt angeben.

von 🐧 DPA 🐧 (Gast)


Lesenswert?

Ist mir schon klar, sonst hätte ich ja nicht dort nachgeschaut. Wobei 
ich .net, VC, c#, etc. auch vorher noch nie gebraucht habe.

von Heinz B. (Firma: Privat) (hbrill)


Lesenswert?

Was gibt denn die normale Chr() - Funktion bzw. ChrW() - Funktion  aus ?
Was du da bekommst (\u00f6) ist ja kein direkt formatierter
Unicode-String. Der ist nur gekennzeichnet mit \u, daß es UTF
ist und dahinter in hexadezimaler Form (0x00f6 oder $00f6)
der Wert in der Zeichentabelle. Normalerweise müßtest du sowas
¶ bekommen. Ein A mit ~ obendrauf und so ein Notenzeichen.

Ich weiß jetzt zwar nicht, wie VB da arbeitet, aber mit meinem
Basic geht Chr$(246) bzw. Chr$($00f6). Vielleicht kannst du ja
das aufdröseln, indem du nach der Einleitung "\u" und danach
die 4 Bytes mit Val von Hex nach Dez wandelst, sofern dein Chr()
keine Hexzahlen versteht. Wie ich sehe, hat VB noch mehrere Chr-
Varianten, z.B. ChrW(). Damit könntest du das dann auch mal
versuchen.

Das Problem ist eher, daß der Editor deiner Programmiersprache
und auch die Controls (Text, Edit, Mulitedit und alles andere,
was Text anzeigt) im ANSI-Modus arbeiten. Auch die Zwischenablage
wandelt ein ö in \u00f6 um.

: Bearbeitet durch User
von Schlaumaier (Gast)


Lesenswert?

Kleine Idee am Rande.

Da dein Zeichencode 4 stellig ist, ist ja wohl klar das du immer die -16 
Variante nehmen musst.

Davon abgesehen ist es wie ich gerade gesehen habe KEIN normaler 
UTF-Code sondern eine JAVA-Code.

Hier schön beschrieben.

https://www.fileformat.info/info/unicode/char/00f6/index.htm

Wieso können die sich nicht auf einen einigen. Den Mist hatte ich schon 
als ich mein ersten Drucker via Mäuseklavier auf den US-Satz (IBM-1) 
eingestellt habe damit er mit deutschen Sonderzeichen sauber lief.

von Schlaumaier (Gast)


Lesenswert?

Mein TIPP.

Replace das */u* gegen 0x  und wandele den Mist dann als Quelle UTF-16 
<- sechszehn  um , weil es ein 2 Bytes Code ist.

von c-hater (Gast)


Lesenswert?

MaWin schrieb:

> Das ö ist kein ASCII char. (Das A steht für American. Die haben keine
> ös)
> Vermutlich ist dein encoding Latin-1 statt ASCII.

Nein, das Encoding des Strings ist wirklich ASCII. Genau deswegen sind 
die Zeichen, die nicht in ASCII passen, escaped.

Das ursprüngliche Encoding (also vor dem Escaping) dürfte allerdings 
tatsächlich Latin-1 gewesen sein. Oder was ähnliches, das lässt sich 
nicht eindeutig allein aus dem Beispielstring ermitteln, könnte z.B. 
genausogut Windows-1252 gewesen sein.

Sprich: um das in jedem Fall korrekt zu was auch immer zu wandeln, muss 
das ursprüngliche Encoding vorab bekannt sein.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.