2010-12-30 22 views
7

Zastanawiam się, jaka jest najlepsza praktyka do analizowania i sprawdzania numeru telefonu komórkowego przed wysłaniem tekstu. Mam kod, który działa, ale chciałbym znaleźć lepsze sposoby na zrobienie tego (jak moje ostatnie pytanie, jest to część mojej wczesnej noworocznej rozdzielczości napisania lepszej jakości kodu!).Najlepsza procedura do analizowania i sprawdzania numeru telefonu komórkowego

W chwili obecnej jesteśmy bardzo wyrozumiali, gdy użytkownik wpisuje numer w formularzu, może wprowadzić takie słowa, jak "+44 123 4567890", "00441234567890", "", "+44 (0) 123456789", "012-345-6789" lub nawet "nie masz telefonu".

Jednak, aby wysłać tekst, format musi być w formacie 44xxxxxxxxxx (dotyczy to tylko brytyjskich telefonów komórkowych), dlatego przed wysłaniem musimy go przeanalizować i zweryfikować. Poniżej znajduje się kod, który mam na razie (C#, asp.net), byłoby świetnie, gdyby ktoś miał jakieś pomysły, jak to poprawić.

Dzięki,

Annelie

private bool IsMobileNumberValid(string mobileNumber) 
    { 
     // parse the number 
     _mobileNumber = ParsedMobileNumber(mobileNumber); 

     // check if it's the right length 
     if (_mobileNumber.Length != 12) 
     { 
      return false; 
     } 

     // check if it contains non-numeric characters 
     if(!Regex.IsMatch(_mobileNumber, @"^[-+]?[0-9]*\.?[0-9]+$")) 
     { 
      return false; 
     } 

     return true; 
    } 

    private string ParsedMobileNumber(string number) 
    { 
     number = number.Replace("+", ""); 
     number = number.Replace(".", ""); 
     number = number.Replace(" ", ""); 
     number = number.Replace("-", ""); 
     number = number.Replace("/", ""); 
     number = number.Replace("(", ""); 
     number = number.Replace(")", ""); 

     number = number.Trim(new char[] { '0' }); 

     if (!number.StartsWith("44")) 
     { 
      number = "44" + number; 
     } 

     return number; 
    } 

EDIT

Oto, co skończyło się z:

private bool IsMobileNumberValid(string mobileNumber) 
    { 
     // remove all non-numeric characters 
     _mobileNumber = CleanNumber(mobileNumber); 

     // trim any leading zeros 
     _mobileNumber = _mobileNumber.TrimStart(new char[] { '0' }); 

     // check for this in case they've entered 44 (0)xxxxxxxxx or similar 
     if (_mobileNumber.StartsWith("440")) 
     { 
      _mobileNumber = _mobileNumber.Remove(2, 1); 
     } 

     // add country code if they haven't entered it 
     if (!_mobileNumber.StartsWith("44")) 
     { 
      _mobileNumber = "44" + _mobileNumber; 
     } 

     // check if it's the right length 
     if (_mobileNumber.Length != 12) 
     { 
      return false; 
     } 

     return true; 
    } 

    private string CleanNumber(string phone) 
    { 
     Regex digitsOnly = new Regex(@"[^\d]"); 
     return digitsOnly.Replace(phone, ""); 
    } 
+1

Przyciąć wiodące zero zamiast zastępować "0044". –

+0

Świetny punkt, już go edytowałem, dzięki! – annelie

+1

Nie można po prostu przyciąć początkowych zer, ponieważ "0712345678" stanie się "712345678". Również liczba.Trim wyrówna końcowe i wiodące zera, co również jest złym pomysłem. – Polyfun

Odpowiedz

2

Użyj wyrażeń regularnych, aby usunąć nie-liczbowe znaki zamiast próbować odgadnąć, w jaki sposób dana osoba wprowadzi ich numer - spowoduje to usunięcie wszystkich metod Replace() i Trim(), chyba że naprawdę trzeba przyciąć wiodącą zero.

string CleanPhone(string phone) 
{ 
    Regex digitsOnly = new Regex(@"[^\d]"); 
    return digitsOnly.Replace(phone, ""); 
} 

Alternatywnie, polecam użyć zamaskowanego pole tekstowe do zbierania # (istnieje wiele opcji dostępna), aby pozwolić tylko wejście numeryczną i wyświetlać dane wejściowe z dowolnym formacie chcesz. W ten sposób gwarantujesz, że otrzymana wartość będzie wszystkimi znakami numerycznymi.

+0

Dokumentacja, którą mam dla bramki SMS, określiła jako format 44xxxxxxxxxx format, możliwe, że akceptują również +44, 0044 i 0xxxxxxxxx. Chcemy jednak, aby mogli oni wpisać którykolwiek z nich w formularzu, a nawet jeśli jest w porządku, aby wprowadzić tam numer spoza Wielkiej Brytanii, musimy upewnić się, że teksty są wysyłane tylko na numery w Wielkiej Brytanii.Być może połączenie tego z metodami wykończenia i wymiany jest drogą do zrobienia? – annelie

+0

Jeśli potrzebujesz akceptować szeroki wachlarz formatów, to maskowane pole tekstowe może nie być właściwą drogą, ponieważ nie mogę wymyślić sposobu, aby uczynić go generycznym wystarczającym dla twoich wymagań. Jednak powyższa metoda będzie bardzo przydatna do usuwania wszelkich nie-numerycznych znaków z łańcucha wejściowego. – Keith

+0

Tak, przepyszne, dzięki! Zaktualizuję mój nowy kod. – annelie

0

@annelie może można zaktualizować wyrażenia regularnego do A bardziej potężny. Sprawdź tę stronę here. Zawiera wiele wyrażeń, ale myślę, że jedno z dwóch najlepszych wyrażeń w witrynie powinno być odpowiednie dla ciebie.

0
public class PhoneNumber 
{ 
    public PhoneNumber(string value) 
    { 
     if (String.IsNullOrEmpty(value)) 
      throw new ArgumentNullException("numberString", Properties.Resources.PhoneNumberIsNullOrEmpty); 

     var match = new Regex(@"\+(\w+) \((\w+)\) (\w+)", RegexOptions.Compiled).Match(value); 
     if (match.Success) 
     { 
      ushort countryCode = 0; 
      ushort localCode = 0; 
      int number = 0; 

      if (UInt16.TryParse(match.Result("$1"), out countryCode) && 
       UInt16.TryParse(match.Result("$2"), out localCode) && 
       Int32.TryParse(match.Result("$3"), out number)) 
      { 
       this.CountryCode = countryCode; 
       this.LocalCode = localCode; 
       this.Number = number; 
      } 
     } 
     else 
     { 
      throw new ArgumentNullException("numberString", Properties.Resources.PhoneNumberInvalid); 
     } 
    } 

    public PhoneNumber(int countryCode, int localCode, int number) 
    { 
     if (countryCode == 0) 
      throw new ArgumentOutOfRangeException("countryCode", Properties.Resources.PhoneNumberIsNullOrEmpty); 
     else if (localCode == 0) 
      throw new ArgumentOutOfRangeException("localCode", Properties.Resources.PhoneNumberIsNullOrEmpty); 
     else if (number == 0) 
      throw new ArgumentOutOfRangeException("number", Properties.Resources.PhoneNumberIsNullOrEmpty); 

     this.CountryCode = countryCode; 
     this.LocalCode = localCode; 
     this.Number = number; 
    } 

    public int CountryCode { get; set; } 

    public int LocalCode { get; set; } 

    public int Number { get; set; } 

    public override string ToString() 
    { 
     return String.Format(System.Globalization.CultureInfo.CurrentCulture, "+{0} ({1}) {2}", CountryCode, LocalCode, Number); 
    } 

    public static bool Validate(string value) 
    { 
     return new Regex(@"\+\w+ \(\w+\) \w+", RegexOptions.Compiled).IsMatch(value); 
    } 

    public static bool Validate(string countryCode, string localCode, string number, out PhoneNumber phoneNumber) 
    { 
     var valid = false; 
     phoneNumber = null; 
     try 
     { 
      ushort uCountryCode = 0; 
      ushort uLocalCode = 0; 
      int iNumber = 0; 

      // match only if all three numbers have been parsed successfully 
      valid = UInt16.TryParse(countryCode, out uCountryCode) && 
        UInt16.TryParse(localCode, out uLocalCode) && 
        Int32.TryParse(number, out iNumber); 

      if (valid) 
       phoneNumber = new PhoneNumber(uCountryCode, uLocalCode, iNumber); 
     } 
     catch (ArgumentException) 
     { 
      // still not match 
     } 
     return valid; 
    } 
} 
Powiązane problemy