Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi Regulärer Ausdruck für Hexzahlen (https://www.delphipraxis.net/195836-regulaerer-ausdruck-fuer-hexzahlen.html)

Ghostwalker 30. Mär 2018 10:06

Regulärer Ausdruck für Hexzahlen
 
Moinmoin,

Ich möchte einen String, der eine Hexzahl repräsentiert, in seine Bytes zerlegen.

Der Ausdruck, den ich soweit zusammengefriggelt habe ist
Code:
^([\$])?([a-f,A-F,0-9]{2}){1,8}$
"The Regulator" (Testprogramm für reguläre Ausdrücke) zeigt mir auch wunderbar die einzelnen Element an.

Das ganze mit Delphi:

Delphi-Quellcode:
var
  reg : TRegEx;
  erg : TMatchCollection;
  mm,it : TMatch;
  gr : TGroup;
  g,m,id  : integer;

begin
  reg := TRegEx.Create('^([\$])?([a-f,A-F,0-9]{2}){1,8}$');
  erg := Reg.Matches('$aabbcc');
  mlog.Lines.Clear;
  if (erg.Count > 0) then
  begin
    for m := 0 to erg.Count -1 do
    begin
      mlog.Lines.Append('Match ('+IntToStr(m)+')');
      mm := erg.Item[m];
      if (mm.Groups.Count > 0) then
      begin
        for g := 0 to mm.Groups.Count -1 do
        begin
          gr := mm.Groups.Item[g];
          mlog.Lines.Append('Group ('+IntToStr(m)+'/'+IntToStr(g)+'):'+gr.Value);

        end;
      end;
    end;
  end;
end;
ergibt aber was gaaaanz anderes:

Code:
Match (0)
Group (0/0):$aabbcc
Group (0/1):$
Group (0/2):cc
Kann mir da kurz jemand helfen ? :)

KodeZwerg 30. Mär 2018 10:11

AW: Regulärer Ausdruck für Hexzahlen
 
Delphi-Quellcode:
function StringtoHex(Data: string): string;
var
  i, i2: Integer;
  s: string;
begin
  i2 := 1;
  for i := 1 to Length(Data) do
  begin
    Inc(i2);
    if i2 = 2 then
    begin
      s := s + ' ';
      i2 := 1;
    end;
    s := s + IntToHex(Ord(Data[i]), 2);
  end;
  Result := s;
end;
Wie der Name sagt, String in einen Hex-String umwandeln.

Uwe Raabe 30. Mär 2018 10:22

AW: Regulärer Ausdruck für Hexzahlen
 
Zitat:

Zitat von Ghostwalker (Beitrag 1397647)
Ich möchte einen String, der eine Hexzahl repräsentiert, in seine Bytes zerlegen.

Zitat:

Zitat von KodeZwerg (Beitrag 1397648)
Wie der Name sagt, String in einen Hex-String umwandeln.

:gruebel:

GPRSNerd 30. Mär 2018 11:30

AW: Regulärer Ausdruck für Hexzahlen
 
Zitat:

Zitat von KodeZwerg (Beitrag 1397648)
Delphi-Quellcode:
function StringtoHex(Data: string): string;
var
  i, i2: Integer;
  s: string;
begin
  i2 := 1;
  for i := 1 to Length(Data) do
  begin
    Inc(i2);
    if i2 = 2 then
    begin
      s := s + ' ';
      i2 := 1;
    end;
    s := s + IntToHex(Ord(Data[i]), 2);
  end;
  Result := s;
end;
Wie der Name sagt, String in einen Hex-String umwandeln.

Liest du eigentlich die Fragen richtig und komplett oder haust du immer einfach nur was raus, wo wenigstens ein Wort übereinstimmt?

KodeZwerg 30. Mär 2018 12:06

AW: Regulärer Ausdruck für Hexzahlen
 
Ok, erwischt, ich bin mit Tablet draussen beim Eiersuchen, Wetter ist ja fantastisch, da hab ich wohl nicht richtig hingeschaut.
Ich ging davon aus das ein String in ein Hex-Wert verwandelt werden sollte.
Ich schau nachher nochmal rein wenn ich am "grossen" Sitze.

SProske 30. Mär 2018 13:08

AW: Regulärer Ausdruck für Hexzahlen
 
Werden in einem regulären Ausdruck sogenennate "capturing groups" wiederholt, so wird nur der letzte Treffer gespeichert, bspw.

Delphi-Quellcode:
(.{2})+
auf einen string abcd losgelassen ergibt als Gesamtmatch wieder abcd, die erste Gruppe enthält aber nur cd. Das ist nichts delphi-spezifisches, sondern gilt für alle PCRE Implementierungen (es gibt aber durchaus Regex-Implementierungen, die erlauben alle Instanzen der Gruppe zu prüfen, z.B. in .net)

Für das was du erreichen willst, gibt es quasi zwei Möglichkeiten
- in einem ersten Schritt den kompletten Hex-String extrahieren und dann in einem zweiten Schritt in 2er Paare unterteilen
- die Nutzung von \G um nach einem erfolgten Match an der selben Stelle wieder anzusetzen

z.B. so:

Delphi-Quellcode:
program Hello;

uses
  System.RegularExpressions;

const
  HEX_STR = '$aabbcc';
var
  M: TMatch;
begin
  M := TRegex.Match(HEX_STR, '(?:^\$?|\G(?!^))([[:xdigit:]]{2})');
  while M.Success do
  begin
    WriteLn(M.Groups[1].Value);
    M := M.NextMatch;
  end;
  ReadLn;
end.
Ich verwende hier die vordefinierte Klasse
Delphi-Quellcode:
[[:xdigit:]]
, die
Delphi-Quellcode:
[a-fA-F0-9]
entspricht. Dein
Delphi-Quellcode:
[a-f,A-F,0-9]
matcht btw. auch Kommas.

Wenn du sicher gehen willst, dass du auch wirklich einen Hex-String mit einer geraden Anzahl von Stelle hast, kann an das Ende des Pattern noch ein
Delphi-Quellcode:
(?=(?:[[:xdigit:]]{2})+$)
.

Uwe Raabe 30. Mär 2018 14:42

AW: Regulärer Ausdruck für Hexzahlen
 
Man kann sich die Sache aber auch deutlich einfacher machen:
Delphi-Quellcode:
var
  rec: Int64Rec;
  I: Integer;
begin
  UINT64(rec) := StrToUInt64('$aabbcc');
  for I := 0 to 7 do begin
    Writeln('$' + rec.Bytes[I].ToHexString(2));
  end;
end;

arnold mueller 30. Mär 2018 15:07

AW: Regulärer Ausdruck für Hexzahlen
 
In System.Classes gibt es BinToHex und umgekehrt.

http://docwiki.embarcadero.com/Libra...asses.HexToBin

Wenn man darum eine Wrapper Funktion baut, die String bzw. TBytes verarbeitet, wäre das relativ elegant.

Ghostwalker 30. Mär 2018 16:26

AW: Regulärer Ausdruck für Hexzahlen
 
Danke erstmal für eure Antworten. Da ich hier mit RegEx arbeiten möchte hab ich mal mit SProske Variante gearbeitet.

Das mit den "," in der Liste ist natürlich ein Tipp-Fehler gewesen :) Das es dafür eine eigene Klasse gibt
wusst ich nicht.

Tut auch soweit bis auf 2 Probleme:

1. Das $-Zeichen (oder eben nichts) sollte ein unabhängiger Match sein

also quasi
Code:
  Match 1: $
  Match 2: aa
  Match 3: BB
  Match 4: cc
2. Der zweite Teil (also quasi die Bytes) sollen min 1 max 8 sein so das
man das ganze im Zweifelsfall als einen Integer (Int64) umwandeln kann.

SProske 30. Mär 2018 16:51

AW: Regulärer Ausdruck für Hexzahlen
 
Na das wird.. unschön - so in etwa:

Delphi-Quellcode:
program HexCheck;

uses
  System.RegularExpressions, System.SysUtils;

const
  HEX_STRINGS: array[0..6] of string = ('$AA', '00', '$AA00BB11CC22DD33', 'AA00BB11CC22DD33', 'A', 'XX1100', '$AA00BB11CC22DD33EE');
var
  M: TMatch;
  S: string;
  I: Integer;
begin
  for S in HEX_STRINGS do
  begin
    WriteLn(Format('Testing %s', [S]));
    I := 0;
    M := TRegex.Match(S, '(?:^\$(?=(?:[[:xdigit:]]{2}){1,8}$)|\G([[:xdigit:]]{2})(?=(?:[[:xdigit:]]{2}){0,7}$))');
    if M.Success then
    begin
      repeat
        WriteLn(Format('%d: %s', [I, M.Groups[0].Value]));
        Inc(I);
        M := M.NextMatch;
      until not M.Success;
    end else
      WriteLn(Format('No match for %s', [S]));
  end;
  ReadLn;
end.


Alle Zeitangaben in WEZ +1. Es ist jetzt 03:53 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz