AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Nummernangaben parsen

Ein Thema von Chewie · begonnen am 4. Nov 2002 · letzter Beitrag vom 4. Nov 2002
Antwort Antwort
Chewie

Registriert seit: 10. Jun 2002
Ort: Deidesheim
2.886 Beiträge
 
Turbo Delphi für Win32
 
#1

Nummernangaben parsen

  Alt 4. Nov 2002, 14:16
Die folgende Funktion bietet die Möglichkeit, aus einem String, in dem Zahlen stehen, ein Array mit diesen Zahlen zu erstellen.
Die Zahlen können sowohl einzeln mit Komma oder Strichpunkt getrennt stehen oder man kann einen Bereich angeben. Die Bereichs-Grenzen werden mit einem Bindestrich verknüpft.

Ein solcher String könnte z. B. so aussehen: 1-100,3306,8000,35000-36000

Alles klar? Mit dieser Funktion sollte das gehen:
Delphi-Quellcode:
type
  TWordList = Array of Word;
  TCharArray = Array of Char;

function ParseList(PortList: String): TWordList;
  function MakeWordNumber(List: TCharArray; size: Integer): Integer;
  var
    a: Integer;
    buf: String;
  begin
    buf := '';
    for a := 0 to size - 1 do
    begin
      buf := buf + List[a];
    end;
    Result := StrToIntDef(buf, -1);
  end;
var
  a, b, c, ResLen, PortListLen: Integer;
  CharSet: set of '0'..'9';
  buf: TCharArray;
  RangeOperator: Boolean;
  loRange, hiRange, Single: Integer;
const
  MaxNumber = 65535;
begin
  if PortList = 'then
  begin
    Result := nil;
    Exit;
  end;
  Result := nil;
  a := 1;
  b := 0;
  CharSet := ['0'..'9'];
  RangeOperator := False;
  PortListLen := Length(PortList);
  //Falls erstes Zeichen eine Ziffer -> Los gehts
  if PortList[a] in CharSet then
  begin
    //Verknüpfungs-Operatoren werden vereinheitlicht
    PortList := StringReplace(PortList, ';', ',', [rfReplaceAll]);
    if PortList[PortListLen] <> ',then Portlist := PortList + ',';
    SetLength(buf, PortListLen);
    buf[b] := PortList[a];
    Inc(b);
    Inc(a);
    //Diese Schleife parst den String
    while PortList[a] <> #0 do
    begin
      //falls Zeichen eine Ziffer ist...
      if PortList[a] in CharSet then
      begin
        {wird sie in einen Puffer geschrieben}
        buf[b] := PortList[a];
        Inc(b);
      end
      else
      begin
        //falls Bereichs-Operator
        if PortList[a] = '-then
        begin
          //falls Bereichs-Operator nicht vorher gesetzt war
          if not RangeOperator then
          begin
            //Bereichs-Operator wird gesetzt, eine Zahl wird aus den vorherigen Zeichen gebildet
            //und der Puffer wird geleert
            RangeOperator := True;
            loRange := MakeWordNumber(buf, b + 1);
            ZeroMemory(@buf, SizeOf(buf));
            SetLength(buf, PortListLen);
            b := 0;
            //falls keine Zahl gebildet werden kann -> Abbruch
            if loRange = -1 then
            begin
              Exit;
            end;
          end
          //falls Bereichs-Operator zweimal hintereinander vorkommt -> Abbruch
          else
          begin
            Exit;
          end;
        end
        //falls Verknüpfungs-Operator
        else if PortList[a] = ',then
        begin
          //falls Bereichs-Operator vorher gesetzt war
          if RangeOperator then
          begin
            //Bereichs-Operator wird zurückgesetzt, Zahl wird aus den vorherigen Ziffern gebildet
            RangeOperator := False;
            hiRange := MakeWordNumber(buf, b + 1);
            ZeroMemory(@buf, SizeOf(buf));
            SetLength(buf, PortListLen);
            b := 0;
            //Falls Zahl nicht gebildet werden konnte -> Abbruch
            if hiRange = -1 then
            begin
              Exit;
            end
            else
            //Falls Zahl gebildet werden konnte
            begin
              //Falls untere Zahl größer als obere -> Abbruch
              if loRange >= HiRange then Exit;
              //falls Nummer größer als 65535 -> Abbruch
              if hiRange > MaxNumber then Exit;
              //Ergebnis-Array auf neue Länge setzen
              ResLen := Length(result);
              SetLength(Result, ResLen + hiRange - loRange + 1);
              {Ergebnis-Array mit Zahlen füllen}
              for c := ResLen to Length(Result) - 1 do
              begin
                Result[c] := loRange;
                Inc(loRange);
              end;
              //Bereichs-Grenzen zurücksetzen
              hiRange := 0;
              loRange := 0;
            end;
          end
          //falls Bereichs-Operator nicht gesetzt war
          else
          begin
            Single := MakeWordnumber(buf, b + 1);
            ZeroMemory(@buf, SizeOf(buf));
            SetLength(buf, PortListLen);
            b := 0;
            //falls Nummer größer als 65535 -> Abbruch
            if Single > MaxNumber then Exit;
            //falls keine gültige Zahl -> Abbruch
            if Single = -1 then
            begin
              Exit;
            end
            //Falls gültige Zahl
            else
            begin
              //Wert wird dem Array hinzugefügt
              SetLength(Result, Length(Result) + 1);
              Result[Length(Result) - 1] := Single;
              Single := 0;
            end;
          end;
        end
        //falls unbekannter Operator -> Abbruch
        else
        begin
          Exit;
        end;
      end;
      Inc(a);
    end;
  end
  else begin
    Exit;
  end;
end;

//Aufruf:
var
  WordList: TWordList;
begin
  WordList := ParseList('1-100,3306,5000-5100');
end;
Falls ihr Fehlerberichte oder Verbesserungsvorschläge habt, bin ich dankbbar.
Auch wenn ihr mir sagt, dass ich das ganze mit Routinen, die mir Delphi liefert, viel einfacher hätte machen können, werde ich nicht böse
Martin Leim
Egal wie dumm man selbst ist, es gibt immer andere, die noch dümmer sind
  Mit Zitat antworten Zitat
jbg

Registriert seit: 12. Jun 2002
3.482 Beiträge
 
Delphi 10.1 Berlin Professional
 
#2
  Alt 4. Nov 2002, 16:16
Dein Code sieht schon ein bisschen umfangreich aus.

Der folgende Code erledigt genau dasselbe. Nur ist er etwas kompakter.
Code:
[b]type[/b]
  TWordList = [b]Array[/b] [b]of[/b] Word;
  TCharArray = [b]Array[/b] [b]of[/b] Char;

[b]function[/b] ParseList([b]const[/b] PortList: [b]String[/b]): TWordList;
[b]var[/b]
  F, P, Sep: PChar;
  s: [b]string[/b];
  i, Len, LoRange, HiRange: Integer;
[b]begin[/b]
  SetLength(Result, 0);

  F := PChar(PortList);
  P := F;
  [b]while[/b] P^ <> #0 [b]do[/b]
  [b]begin[/b]
    [b]while[/b] (P^ <> #0) [b]and[/b] ([b]not[/b] (P^ [b]in[/b] ['-', ',', ';'])) [b]do[/b] Inc(P);

    [b]if[/b] P^ = '-' [b]then[/b]
    [b]begin[/b]
      Sep := P;
     [color=#000080][i]// Ende suchen[/i][/color]
      [b]while[/b] (P^ <> #0) [b]and[/b] ([b]not[/b] (P^ [b]in[/b] [',', ';'])) [b]do[/b] Inc(P);
      SetString(s, F, Sep - F);
      LoRange := StrToIntDef(s, -1);
      Inc(Sep);
      SetString(s, Sep, P - Sep);
      HiRange := StrToIntDef(s, -1);
    [b]end[/b] [b]else[/b]
    [b]begin[/b]
      SetString(s, F, P - F);
      LoRange := StrToIntDef(s, -1);
      HiRange := LoRange;
    [b]end[/b];
    [b]if[/b] (LoRange = -1) [b]or[/b] (HiRange = -1) [b]or[/b]
       (LoRange > HiRange) [b]or[/b] (HiRange > High(Word))[b]then[/b]
      [b]raise[/b] Exception.Create('Ungültige Port Liste');
    Len := Length(Result);
    SetLength(Result, Len + HiRange - LoRange + 1);
    [b]for[/b] i := LoRange [b]to[/b] HiRange [b]do[/b]
      Result[Len + i - LoRange] := i;

    [b]if[/b] P^ <> #0 [b]then[/b] Inc(P); [color=#000080][i]// ';', '-' überspringen[/i][/color]
    F := P;
  [b]end[/b];
[b]end[/b];
  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 23:12 Uhr.
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