Thema: Delphi Handynummer zu ordnen

Einzelnen Beitrag anzeigen

nahpets
(Gast)

n/a Beiträge
 
#46

Re: Handynummer zu ordnen

  Alt 20. Okt 2008, 09:43
Hallo,

nachdem ich mit den bisher erreichten Ergebnissen beim Vergleich von Telefonnummern nicht zufrieden war, hab' ich mir 'ne Komponente für diese Aufgabe geschrieben.

Eventuell hat ja noch jemand Interesse daran.

Delphi-Quellcode:
{
  Komponente zum Vergleich von Telefonnummern:
  Es wird davon ausgegangen, dass die bekannte Telefonnummer folgenden Aufbau hat:
  Nationaler Exitcode
+ Landesvorwahl
+ Ortsvorwahl (ohne führende 0, sofern national zulässig)
+ Telefonnummer
  Beispiele: 004930123456789, 003906123456789, 0049171123456789
}

unit CheckPhoneNumber;

interface

uses
  SysUtils, Classes;

type TTypeOfAreaCode = (acNormal, acItaly);

type
  TCheckPhoneNumber = class(TComponent)
  private
    { Private-Deklarationen }
    FNationalExitCode : String; // 00 -> Vorwahl ins Ausland
    FReverseNationalExitCode : String; // FNationalExitCode in umgekehrter Zeichenfolge
    FCountryCode : String; // 49 -> Landesvorwahl
    FReverseCountryCode : String; // FCountryCode in umgekehrter Zeichenfolge
    FAreaCode : String; // 0511 -> Vorwahl
    FReverseAreaCode : String; // FAreaCode in umgekehrter Zeichenfolge
    FInternExitCode : String; // Vorwahl für Amt
    FReverseInternExitCode : String; // FInternExitCode in umgekehrter Zeichenfolge
    FPhoneNumber : String; // Telefonnummer
    FReversePhoneNumber : String; // FPhoneNumber in umgekehrter Zeichenfolge
    FUnknownPhoneNumber : String; // Telefonnummer, die auf Gleichheit geprüft werden soll
    FReverseUnknownPhoneNumber : String; // FUnknownPhoneNumber in umgekehrter Zeichenfolge

    FTypeOfAreaCode : TTypeOfAreaCode; // Art des Vergleiches
    FEqualPhoneNumbers : Boolean; // True wenn Telefonnummern übereinstimmen
  protected
    { Protected-Deklarationen }
    function NormalizePhoneNumber(AValue : String) : String;
    function ComparePhoneNumbers(No1 : String; No2 : String) : Integer; overload;
    function ComparePhoneNumbers : Boolean; overload;
    function AddFirst0(No : String) : String;
    function RemoveFirst0(No : String) : String;

    procedure SetAreaCode(AValue : String);
    procedure SetCountryCode(AValue : String);
    procedure SetInternExitCode(AValue : String);
    procedure SetNationalExitCode(AValue : String);
    procedure SetPhoneNumber(AValue : String);
    procedure SetUnknownPhoneNumber(AValue : String);

    procedure SetTypeOfAreaCode(AValue : TTypeOfAreaCode);
    procedure SetEqualPhoneNumbers(AValue : Boolean);
  public
    { Public-Deklarationen }
  published
    { Published-Deklarationen }
    property AreaCode : String Read FAreaCode Write SetAreaCode;
    property CountryCode : String Read FCountryCode Write SetCountryCode;
    property InternExitCode : String Read FInternExitCode Write SetInternExitCode;
    property NationalExitCode : String Read FNationalExitCode Write SetNationalExitCode;
    property PhoneNumber : String Read FPhoneNumber Write SetPhoneNumber;
    property UnknownPhoneNumber : String Read FUnknownPhoneNumber Write SetUnknownPhoneNumber;
    property TypeOfAreaCode : TTypeOfAreaCode Read FTypeOfAreaCode Write SetTypeOfAreaCode;
    property EqualPhoneNumbers : Boolean Read FEqualPhoneNumbers Write SetEqualPhoneNumbers;
  end;

procedure Register;

implementation

Uses
     StrUtils, Math;

procedure Register;
begin
  RegisterComponents('TelTools', [TCheckPhoneNumber]);
end;

{ Die Funktion entfernt aus einer Telefonnummer alle Zeichen, bei denen
  es sich nicht um Ziffern handelt. Das Plus wird durch den konfigurierten
  nationalen Exitcode ersetzt.
~param AValue zu beabeitender Wert
~result Um alle "Nichtziffern" bereinigte Telefonnummer}

function TCheckPhoneNumber.NormalizePhoneNumber(AValue : String) : String;
Var
          i : Integer;
          s : String;
begin
  s := '';
  AValue := StringReplace(AValue,'+',FNationalExitCode,[]);
  for i := 1 To Length(AValue) do begin
    Case AValue[i] of
      '0'..'9' : s := s + AValue[i];
    end;
  end;
  Result := s;
end;

{ Die Funktion vergleicht zwei Telefonnummern und liefert die Position des
  ersten Unterschiedes.
~param No1 1. zu vergleichende Telefonnummer
~param No2 2. zu vergleichende Telefonnummer
~result Position des ersten Unterschiedes }

function TCheckPhoneNumber.ComparePhoneNumbers(No1 : String; No2 : String) : Integer;
Var
          i : Integer;
          iMinLength : Integer;
          bNotEqual : Boolean;
begin
  i := 1;
  bNotEqual := True;
  iMinLength := Min(Length(No1),Length(No2));
  if iMinLength > 0 then begin
    repeat
      bNotEqual := (No1[i] <> No2[i]);
      inc(i);
    until bNotEqual or (i > iMinLength);
  end;
  if bNotEqual then begin
    Dec(i);
    Result := i;
  end else begin
    Result := i;
  end;
end;

{ Die Funktion entfernt die führende Vorwahlnull aus einer Telefonnummer,
  sofern dies konfiguriert ist, andernfalls wird sie unverändert zurückgegeben.
  Ist die übergebene Telefonnummer leer, so wird ein X zurückgegeben.
~param No zu bearbeitende Telefonnummer
~result bearbeitete Telefonnummer }

function TCheckPhoneNumber.RemoveFirst0(No : String) : String;
begin
  // Hier gibt es jetzt noch länderspezifische Besonderheiten:
  // In vielen Ländern fällt im Zusammerhang mit der Landesvorwahl bei der
  // Ortsvorwahl die führende 0 weg, nicht so in Italien.
  Case FTypeOfAreaCode of
    acItaly : begin // hier bleibt die führende 0 erhalten
               end;
    acNormal : begin
                 // führende 0 entfernen
                 if Length(No) > 0 then begin
                   Case No[Length(No)] of
                     '0' : begin
                             No := Copy(No,1,Length(No) - 1);
                           end;
                   end;
                 end else begin
                   No := 'X';
                 end;
               end;
  end;
  Result := No;
end;

{ Die Funktion fügt eine führende Vorwahlnull der Telefonnummer hinzu,
  sofern dies konfiguriert ist, andernfalls wird sie unverändert zurückgegeben.
~param No zu bearbeitende Telefonnummer
~result bearbeitete Telefonnummer }

function TCheckPhoneNumber.AddFirst0(No : String) : String;
begin
  // Hier gibt es jetzt noch länderspezifische Besonderheiten:
  // In vielen Ländern fällt im Zusammerhang mit der Landesvorwahl bei der
  // Ortsvorwahl die führende 0 weg, nicht so in Italien.
  Case FTypeOfAreaCode of
    acItaly : begin // hier bleibt die führende 0 erhalten
               end;
    acNormal : begin
                 No := No + '0';
               end;
  end;
  Result := No;
end;

{ Die Funktion vergleicht zwei Telefonnummern und liefert bei Übereinstimmung
  True als Rückgabewert.
~result True oder False }

function TCheckPhoneNumber.ComparePhoneNumbers : Boolean;
Var
          i : Integer;
          bNotEqual : Boolean;
          sPhoneNumber : String;
          sUnknownPhoneNumber : String;
begin
  // Zuerst werden die vollständigen Nummern verglichen.
  bNotEqual := FReversePhoneNumber <> FReverseUnknownPhoneNumber;
  If not bNotEqual Then begin
    Result := Not bNotEqual;
    Exit;
  end;
  // Die Telefonnummer stimmen nicht überein:
  // i enthält die Position des ersten Unterschiedes
  i := ComparePhoneNumbers(FReversePhoneNumber,FReverseUnknownPhoneNumber);
  // Alles ab diesem Unterschied holen.
  sPhoneNumber := Copy(FReversePhoneNumber,i,Length(FReversePhoneNumber));
  sUnknownPhoneNumber := Copy(FReverseUnknownPhoneNumber,i,Length(FReverseUnknownPhoneNumber));
  // Ist das Ergebnis unterschiedlich?
  bNotEqual := sPhoneNumber <> sUnknownPhoneNumber;
  if bNotEqual then begin
    // Ist der verbliebene Rest der unbekannten Telefonnummer leer
    // dann müssen wir prüfen,
    If (sUnknownPhoneNumber = '') then begin
      // ob die verbliebene Telefonnummer mit
      // der Vorwahl, der Landesvorwahl und dem ExitCode übereinstimmt.
      if (sPhoneNumber = RemoveFirst0(FReverseAreaCode) + FReverseCountryCode + FReverseNationalExitCode) then begin
        // Dann prüfen, ob die bekannte Telefonnummer mit der unbekannten
        // Telefonnummer, der Vorwahl, der Landesvorwahl und dem Exitcode übereinstimmt.
        bNotEqual := FReversePhoneNumber <> (FReverseUnknownPhoneNumber
                                           + RemoveFirst0(FReverseAreaCode)
                                           + FReverseCountryCode
                                           + FReverseNationalExitCode);
      end else
      // ob die verbliebene Telefonnummer mit
      // der Landesvorwahl und dem ExitCode übereinstimmt.
      if (sPhoneNumber = FReverseCountryCode + FReverseNationalExitCode) then begin
        // Dann prüfen, ob die bekannte Telefonnummer mit der unbekannten
        // um die führende Vorwahlnull erweiterte Telefonnummer,
        // der Landesvorwahl und dem Exitcode übereinstimmt.
        bNotEqual := FReversePhoneNumber <> (AddFirst0(FReverseUnknownPhoneNumber)
                                           + FReverseCountryCode
                                           + FReverseNationalExitCode);
      end else
      // ob die verbliebene Telefonnummer mit
      // dem ExitCode übereinstimmt.
      if (sPhoneNumber = FReverseNationalExitCode) then begin
        // Dann prüfen, ob die bekannte Telefonnummer mit der unbekannten
        // Telefonnummer und dem Exitcode übereinstimmt.
        bNotEqual := FReversePhoneNumber <> (FReverseUnknownPhoneNumber
                                           + FReverseNationalExitCode);
      end;
    end else
    // Ist der verbliebene Rest der unbekannten Telefonnummer eine 0
    // dann müssen wir prüfen,
    If (sUnknownPhoneNumber = '0') then begin
      // ob die verbliebene Telefonnummer mit
      // der Landesvorwahl und dem ExitCode übereinstimmt.
      if (sPhoneNumber = FReverseCountryCode + FReverseNationalExitCode) then begin
        // Dann prüfen, ob die bekannte Telefonnummer mit der um die Vorwahlnull
        // gekürzten unbekannten Telefonnummer, der Landesvorwahl
        // und dem Exitcode übereinstimmt.
        bNotEqual := FReversePhoneNumber <> (RemoveFirst0(FReverseUnknownPhoneNumber)
                                           + FReverseCountryCode
                                           + FReverseNationalExitCode);
      end;
    end;
  end;
  Result := Not bNotEqual;
end;

procedure TCheckPhoneNumber.SetNationalExitCode(AValue : String);
begin
  FNationalExitCode := NormalizePhoneNumber(AValue);
  FReverseNationalExitCode := ReverseString(FNationalExitCode);
  FEqualPhoneNumbers := ComparePhoneNumbers;
end;

procedure TCheckPhoneNumber.SetCountryCode(AValue : String);
begin
  FCountryCode := NormalizePhoneNumber(AValue);
  FReverseCountryCode := ReverseString(FCountryCode);
  FEqualPhoneNumbers := ComparePhoneNumbers;
end;

procedure TCheckPhoneNumber.SetAreaCode(AValue : String);
begin
  FAreaCode := NormalizePhoneNumber(AValue);
  FReverseAreaCode := ReverseString(FAreaCode);
  FEqualPhoneNumbers := ComparePhoneNumbers;
end;

procedure TCheckPhoneNumber.SetInternExitCode(AValue : String);
begin
  FInternExitCode := NormalizePhoneNumber(AValue);
  FReverseInternExitCode := ReverseString(FInternExitCode);
  FEqualPhoneNumbers := ComparePhoneNumbers;
end;

procedure TCheckPhoneNumber.SetPhoneNumber(AValue : String);
begin
  FPhoneNumber := NormalizePhoneNumber(AValue);
  FReversePhoneNumber := ReverseString(FPhoneNumber);
  FEqualPhoneNumbers := ComparePhoneNumbers;
end;

procedure TCheckPhoneNumber.SetUnknownPhoneNumber(AValue : String);
begin
  FUnknownPhoneNumber := NormalizePhoneNumber(AValue);
  FReverseUnknownPhoneNumber := ReverseString(FUnknownPhoneNumber);
  FEqualPhoneNumbers := ComparePhoneNumbers;
end;

procedure TCheckPhoneNumber.SetTypeOfAreaCode(AValue : TTypeOfAreaCode);
begin
  FTypeOfAreaCode := AValue;
  FEqualPhoneNumbers := ComparePhoneNumbers;
end;

procedure TCheckPhoneNumber.SetEqualPhoneNumbers(AValue : Boolean);
begin
  FEqualPhoneNumbers := ComparePhoneNumbers;
end;

end.
  Mit Zitat antworten Zitat