2010-12-30 34 views
7

Me pregunto cuál es la mejor práctica para analizar y validar un número de teléfono móvil antes de enviar un mensaje de texto. Tengo un código que funciona, pero me gustaría encontrar mejores formas de hacerlo (como mi última pregunta, ¡esto es parte de mi resolución de principios de año nuevo de escribir un código de mejor calidad!).Mejor práctica para analizar y validar el número de teléfono móvil

En el momento en que son muy indulgente cuando el usuario introduce el número en el formulario, pueden entrar en cosas como "+44 123 4567890", "00441234567890", "", "+44 (0) 123456789", "012-345-6789" o incluso "no tengo un teléfono".

Sin embargo, para enviar el texto, el formato debe ser 44xxxxxxxxxx (esto es solo para móviles del Reino Unido), por lo que debemos analizarlo y validarlo antes de poder enviarlo. A continuación está el código que tengo por ahora (C#, asp.net), sería genial si alguien tuviera alguna idea sobre cómo mejorarlo.

Gracias,

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

Esto es lo que terminé con:

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

Recortar cero en lugar de reemplazar "0044". –

+0

Un gran punto, lo he editado ahora, ¡gracias! – annelie

+1

No puede simplemente recortar ceros a la izquierda porque "0712345678" se convertirá en "712345678". También number.Trim recortará los ceros al final y al principio, lo que también es una mala idea. – Polyfun

Respuesta

2

Utilice una expresión regular para eliminar los caracteres no numéricos en lugar de tratar de adivinar cómo una persona ingresará su número: esto eliminará todos sus métodos Reemplazar() y Recortar() a menos que realmente necesite recortar una cero.

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

Alternativamente, recomiendo que utilice un cuadro de texto enmascarado para recoger el # (hay muchas opciones disponibles) para permitir sólo la introducción numérica, y mostrar la entrada con el formato que desea. De esta manera, garantiza que el valor recibido será de caracteres numéricos.

+0

La documentación que tengo para el gateway SMS especificó 44xxxxxxxxxx como el formato para enviar el número, sin embargo, es posible que también acepten +44, 0044 y 0xxxxxxxxx. Sin embargo, queremos que puedan ingresar cualquiera de estos en el formulario, e incluso si está bien que ingresen un número que no sea del Reino Unido, aún debemos asegurarnos de que los mensajes de texto solo se envíen a los británicos.¿Tal vez una combinación de esto y los métodos de recorte y reemplazo es el camino a seguir? – annelie

+0

Si necesita aceptar una amplia variedad de formatos, un cuadro de texto enmascarado podría no ser el camino a seguir, ya que no se me ocurre una manera de hacerlo lo suficientemente genérico para sus requisitos. Sin embargo, el método anterior será muy útil para eliminar cualquier carácter no numérico de la cadena de entrada. – Keith

+0

Sí, trabajó un regalo, gracias! Voy a actualizar con mi nuevo código. – annelie

0

@annelie tal vez usted puede actualizar su expresión regular para una más poderoso. Echa un vistazo a este sitio here. Contiene muchas expresiones, pero creo que una de las dos mejores expresiones en el sitio debería ser adecuada para usted.

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; 
    } 
} 
Cuestiones relacionadas