AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi Zwei Version-Strings (mit Buchstaben) vergleichen
Thema durchsuchen
Ansicht
Themen-Optionen

Zwei Version-Strings (mit Buchstaben) vergleichen

Ein Thema von hypfvieh · begonnen am 17. Feb 2011 · letzter Beitrag vom 17. Feb 2011
Antwort Antwort
Benutzerbild von GPRSNerd
GPRSNerd

Registriert seit: 30. Dez 2004
Ort: Ruhrpott
239 Beiträge
 
Delphi 10.4 Sydney
 
#1

AW: Zwei Version-Strings (mit Buchstaben) vergleichen

  Alt 17. Feb 2011, 14:09
Hier mal ein Versuch, der sich auf numerische Strings (z.B. "1234.1224.1234.1234") mit Separator (Char, default ".") beschränkt.
Die Anzahl der Teilstrings und deren nummerische Größe ist nur limitiert durch die Größe von Int64, da keine Summenzahl aus den Teilstrings gebildet wird, sondern alle Päarchen einzeln miteinander verglichen werden, bis ein eindeutiges Ergebnis feststeht.

Delphi-Quellcode:
type
  //Returntype für Versionsnummern vergleichen
  TValueRelationship = -1..1;

const
  //Returnvalues für Versionsnummern vergleichen
  LessThanValue = Low(TValueRelationship);
  EqualsValue = 0;
  GreaterThanValue = High(TValueRelationship);

function IsNumeric(const s: String): Boolean;
var
  i: Integer;
begin
  Result := False;
  for i := 1 to Length(s) do
    if not CharInSet(s[i], ['0'..'9']) then exit;
  Result := True;
end;

function CompareVersionStrings(const V1, V2: string;
                               const Separator: char = '.'): TValueRelationship;
var
  iV1, iV2: Int64;
  slV1, slV2: TStringList;
  i: Integer;
begin
  Result := EqualsValue; //temp

  //Übergebene Parameter validieren
  if ((V1='') or (V2='') or (Separator='')) then
  begin
    Raise Exception.CreateFmt('CompareVersionStrings: Leere Parameter nicht erlaubt ("%S", "%S", "%S")', [V1, V2, Separator]);
    Exit;
  end;

  slV1 := TStringList.Create;
  slV2 := TStringList.Create;
  try

    //Strings in Teilstrings mit Stringlists zerlegen
    slV1.Delimiter := Separator;
    slV1.DelimitedText := V1;
    slV2.Delimiter := Separator;
    slV2.DelimitedText := V2;
    if ((slV1.Count<>slV2.Count) or (slV1.Count=0) or (slV2.Count=0)) then
    begin
      Raise Exception.CreateFmt('CompareVersionStrings: Anzahl der Teilstrings ist nicht identisch (%D bei "%S", %D bei "%S")', [slV1.Count, V1, slV2.Count, V2]);
      Exit;
    end;

    //Teilstrings auswerten
    for i := 0 to slV1.Count - 1 do
    begin
      if ((slV1[i]='') or (slV2[i]='')) then
      begin
        Raise Exception.CreateFmt('CompareVersionStrings: Leere Teilstrings nicht erlaubt ("%S" bei "%S", "%S" bei "%S")', [slV1[i], V1, slV2[i], V2]);
        Exit;
      end;

      if ((not IsNumeric(slV1[i])) or (not IsNumeric(slV2[i]))) then
      begin
        Raise Exception.CreateFmt('CompareVersionStrings: Teilstrings sind nicht numerisch ("%S" bei "%S", "%S" bei "%S")', [slV1[i], V1, slV2[i], V2]);
        Exit;
      end;

      //In Integerzahlen konvertieren
      try
        iV1 := StrToInt(slV1[i]);
        iV2 := StrToInt(slV2[i]);
      except
        Raise Exception.CreateFmt('CompareVersionStrings: Konvertierung nach Integer nicht erfolgreich ("%S" bei "%S", "%S" bei "%S")', [slV1[i], V1, slV2[i], V2]);
        Exit;
      end;

      //Jetzt Integerzahlen vergleichen
      if iV1<iV2 then
      begin
        Result := LessThanValue;
        Break; //Eindeutiges Ergebnis, Schleife abbrechen
      end
      else if iV1>iV2 then
      begin
        Result := GreaterThanValue;
        Break; //Eindeutiges Ergebnis, Schleife abbrechen
      end
      else
      begin
        //Immer noch gleich, nächstes Paar vergleichen
      end;
    end;

  finally
    FreeAndNil(slV1);
    FreeAndNil(slV2);
  end;
end;
Die folgenden Positiv- und Exception-Unittests waren damit erfolgreich unter Delphi 2010:
Delphi-Quellcode:
  Assert(EqualsValue = CompareVersionStrings('0', '0'));
  Assert(EqualsValue = CompareVersionStrings('1', '1'));
  Assert(EqualsValue = CompareVersionStrings('1.2', '1.2'));
  Assert(EqualsValue = CompareVersionStrings('1.2.3', '1.2.3'));
  Assert(EqualsValue = CompareVersionStrings('1.2.3.4', '1.2.3.4'));
  Assert(EqualsValue = CompareVersionStrings('9999.9999.9999.9999', '9999.9999.9999.9999'));
  Assert(EqualsValue = CompareVersionStrings('99999.99999.99999.99999', '99999.99999.99999.99999'));
  Assert(EqualsValue = CompareVersionStrings('99999.99999.99999.99999.99999', '99999.99999.99999.99999.99999'));

  Assert(LessThanValue = CompareVersionStrings('0', '1'));
  Assert(LessThanValue = CompareVersionStrings('1', '2'));
  Assert(LessThanValue = CompareVersionStrings('1.2', '1.3'));
  Assert(LessThanValue = CompareVersionStrings('1.2.3', '1.2.4'));
  Assert(LessThanValue = CompareVersionStrings('1.2.3.4', '1.2.3.5'));
  Assert(LessThanValue = CompareVersionStrings('9991.9999.9999.9999', '9999.9999.9999.9999'));
  Assert(LessThanValue = CompareVersionStrings('9999.9991.9999.9999', '9999.9999.9999.9999'));
  Assert(LessThanValue = CompareVersionStrings('9999.9999.9991.9999', '9999.9999.9999.9999'));
  Assert(LessThanValue = CompareVersionStrings('9999.9999.9999.9991', '9999.9999.9999.9999'));
  Assert(LessThanValue = CompareVersionStrings('99999.99999.99999.99991', '99999.99999.99999.99999'));
  Assert(LessThanValue = CompareVersionStrings('99999.99999.99999.99999.99991', '99999.99999.99999.99999.99999'));

  Assert(GreaterThanValue = CompareVersionStrings('1', '0'));
  Assert(GreaterThanValue = CompareVersionStrings('2', '1'));
  Assert(GreaterThanValue = CompareVersionStrings('1.3', '1.2'));
  Assert(GreaterThanValue = CompareVersionStrings('1.2.4', '1.2.3'));
  Assert(GreaterThanValue = CompareVersionStrings('1.2.3.5', '1.2.3.4'));
  Assert(GreaterThanValue = CompareVersionStrings('9999.9999.9999.9999', '9991.9999.9999.9999'));
  Assert(GreaterThanValue = CompareVersionStrings('9999.9999.9999.9999', '9999.9991.9999.9999'));
  Assert(GreaterThanValue = CompareVersionStrings('9999.9999.9999.9999', '9999.9999.9991.9999'));
  Assert(GreaterThanValue = CompareVersionStrings('9999.9999.9999.9999', '9999.9999.9999.9991'));
  Assert(GreaterThanValue = CompareVersionStrings('99999.99999.99999.99999', '99999.99999.99999.99991'));
  Assert(GreaterThanValue = CompareVersionStrings('99999.99999.99999.99999.99999', '99999.99999.99999.99999.99991'));

  Assert(EqualsValue = CompareVersionStrings('1,2', '1,2', ','));
  Assert(LessThanValue = CompareVersionStrings('1,2', '1,3', ','));
  Assert(GreaterThanValue = CompareVersionStrings('1,3', '1,2', ','));
  Assert(GreaterThanValue = CompareVersionStrings('9999#9999#9999#9999', '9999#9999#9999#9998', '#'));

  Vergleich: TValueRelationship;
  //Exceptions: Leere Parameter
  try
    Vergleich := CompareVersionStrings('1', '');
  except
  end;
  try
    Vergleich := CompareVersionStrings('', '2');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1', '2', #0);
  except
  end;

  //Exceptions: Ungleiche Counts
  try
    Vergleich := CompareVersionStrings('1.2.3', '1.2.3.4');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1.2.3.4', '1.2.3');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1.2.3', '1.2..4');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1.2..4', '1.2.3');
  except
  end;

  //Exceptions: Leere Teilstrings
  try
    Vergleich := CompareVersionStrings('1.2..4', '1.2.3.4');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1.2.3.4', '1.2..4');
  except
  end;

  //Exceptions: Nichtnumerisch
  try
    Vergleich := CompareVersionStrings('1.2.3A', '1.2.3');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1.2.3', '1.2.3B');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1.2.3A', '1.2.3B');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1.2.3.A', '1.2.3.4');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1.2.3.4', '1.2.3.B');
  except
  end;
  try
    Vergleich := CompareVersionStrings('1.2.3.A', '1.2.3.B');
  except
  end;
//Edit: Exceptionhandling angepasst nach Tests.
Stefan

Geändert von GPRSNerd (17. Feb 2011 um 17:48 Uhr)
  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 00:14 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz