Laden...

String Kette auswerten und Teile in Hexadezimal umrechnen

Erstellt von Krachgarten vor 6 Jahren Letzter Beitrag vor 6 Jahren 1.846 Views
K
Krachgarten Themenstarter:in
8 Beiträge seit 2017
vor 6 Jahren
String Kette auswerten und Teile in Hexadezimal umrechnen

Guten Tag ,

ich habe aktuell im Rahmen meines Techniker Projektes ein Problem!

Aktuell baue ich ein Programm um eine Druckereinheit für Parkscheinautomaten am PC zu testen.

Also die Serielle anbindung etc. funktioniert so weit.

Ich möchte nun in eine Textbox eine Befehlskette eintragen die der Drucker ausführen soll, dazu muss diese Befehlskette aber in Hexadezimal umgerechnet werden (laut Ascii Code)

Soweit alles kein Problem, nur bekomme ich es nur hin das mir jedes einzelne Zeichen umgerechnet wird. Also z.B aus 13(dezimal) wird dann 0x31 und 0x33 anstatt 0x0D.

Also ich muss irgendwie zum ersten auswerten können ob ich eine dezimal Zahl auswerten will, diese wird dann z.B <13d> in meiner Befehlskette geschrieben (dementsprechend muss das "d" und die Pfeile davor ignoriert werden) oder ob ich die 13 als einzelne Zeichen auswerten will.

Damit es klarer wird hier mal ein Beispiel: Eine Befehlskette könnte z.B so aussehen

@<ESC>C<0d> und das müsste aufgesplittet werden in @ <ESC> C <0d> und die endgültige ausgabe in hex (laut ascii) wäre dann 0x40 0x1B 0x43 0x00

hätte jemand eine Idee wie man sowas realisieren könnte?

Grüße Krachgarten

3.003 Beiträge seit 2006
vor 6 Jahren
  1. falsches Forum 😃


//Pseudocode
1. Trenne Zeile auf in Bestandteile, die in <> stehen, und alle anderen Bestandteile
2. Erstelle eine Liste aus diesen Bestandteilen
3. für jedes Listenelement
3.1. steht es in <> ? 
3.1.1 ja - endet der Wert auf d? 
3.1.1.1 ja - nimm den Bestandteil vor dem d, interpretiere ihn dezimal, und rechne in Hex um
3.1.1.2 nein - interpretiere den Wert anhand einer Tabelle von Steuerzeichen (ESC = 0x1B, CR = 0x0D)
3.1.2 nein - interpretiere den Wert als ASCII und suche den hex-Wert
3.2 packe das Ergebnis in eine Ergebnisliste vom Typ byte[]
4. Gib das Byte-Array als Ergebnis aus.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

2.079 Beiträge seit 2012
vor 6 Jahren

Oder mit Regex:

var text = "@<ESC>C<0d>";
var regex = new Regex("<(?<code>[^<>]+)>");
            
text = regex.Replace(text, match =>
{
    var code = match.Groups["code"].Value;
    Console.WriteLine("Steuerzeichen gefunden: " + code);
    // Hier viele coole Ersetzungen, wie LaTino schreibt
    return "[" + code + "]";
});
            
Console.WriteLine();
Console.WriteLine(text);

Ausgabe:

Steuerzeichen gefunden: ESC
Steuerzeichen gefunden: 0d

@[ESC]C[0d]

Das Pattern erlaubt auch die spitzen Klammern in Nicht-Steuerzeichen-Text, solange zwischen diesen spitzen Klammern kein Text ist.
Hier zum Testen: https://regex101.com/r/RvnAV1/2

Wenn in Nicht-Steuerzeichen-Text auch spitze Klammern mit irgendwas dazwischen sein soll, dann musst Du das beim Replace entsprechend abfangen und ignorieren.

3.003 Beiträge seit 2006
vor 6 Jahren

Ist bei mir Schritt eins.

Ich würde dann aber lieber die richtige Regex nehmen und ohne replace arbeiten:


matchStrings = Regex.Matches(example, @"<.+?>|.+?").OfType<Match>().Select(p => p.Value);

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

2.079 Beiträge seit 2012
vor 6 Jahren

Stimmt, sieht besser aus
Wenn Du aus dem Select ein SelectMany machst und darin direkt in binarys umrechnest, bekommst Du direkt das byte-Array raus, was dann als Hex geschrieben werden kann.
Noch ein Aufruf von BitConverter.ToString und die Arbeit getan.

Aber ohne kleinlich sein zu wollen: (.+?

Das ist nicht unbedingt das schnellste.
Besser ist, wenn anstatt des Punktes alle Zeichen außer die spizten Klammern erlaubt sind.
Das hat auch gleich den Vorteil, dass die spitzen Klammern als normales Zeichen erlaubt sind, solange sie nicht korrekt geschlossen werden.

https://regex101.com/r/RvnAV1/3

In meinem zweiten Pattern matche ich nach dem Oder auf ein einzelnes Zeichen.
Ich persönlich finde es so leichter verständlich, da so jedes Match ein "Zeichen" im Kontext (also Zeichen oder Steuerzeichen) darstellt.
Außerdem spare ich mir damit das erzwungene genügsame Verhalten (Fragezeichen nach dem Plus) nach dem Oder, was zumindest theoretisch schneller ist.
Du matchst dagegen den kompletten Text bis zum nächsten Steuerzeichen, das hätte den Vorteil, dass man den ganzen Text als Ganzes als Hex zurück geben kann
Was nun besser ist, ist wohl Geschmackssache, besonders da eventuelle Performance-Unterschiede wahrscheinlich so winzig sind, das sie nicht ins Gewicht fallen.

PS:
Man sollte nicht vergessen, dass ein Int mehr als ein Byte groß ist.
Für die Zahl 12 mag ein 0xC ausreichen, bei deutlich größeren Zahlen reicht das aber nicht mehr.
Das nur als Hinweis