2010-08-20 9 views
30

Tengo una cadena cuando se ingresa un número de teléfono - hay una máscara por lo que siempre se ve como "(123) 456-7890" - Me gustaría sacar el formato antes de guardarlo en la base de datos.Eliminar el formato de una cadena: "(123) 456-7890" => "1234567890"?

¿Cómo puedo hacer eso?

+0

Por cierto, Int.Parse no es parte de C# –

+0

Err, entonces ¿por qué está documentado? http://msdn.microsoft.com/en-us/library/system.int32.parse.aspx –

+4

John Saunders simplemente está equivocado. – Timwi

Respuesta

71

Una posibilidad usando LINQ es:

string justDigits = new string(s.Where(c => char.IsDigit(c)).ToArray()); 

Añadiendo el limpiador/más corto versión gracias a craigmoliver

string justDigits = new string(s.Where(char.IsDigit).ToArray()) 
+0

+1 lindo, tu fuiste un poco más rápido en el sorteo. –

+0

Excepto cuando realmente lo ejecuto, no funciona. Solo un segundo ... –

+0

'SkipWhile' no funcionará para esto. – LukeH

1

Se podría utilizar una expresión regular o usted podría bucle sobre cada personaje y utilizar char.IsNumber función .

4

Puede hacer que funcione para ese número con la adición de un simple reemplazo de expresiones regulares, pero yo buscaría dígitos iniciales más altos. Por ejemplo, (876) 543-2019 desbordará una variable entera.

+0

+1 Buen punto. No pensé en eso. –

+1

Hmm ... alguna parte de mí realmente quiere marcar ese número y ver si es real. Simplemente no sé lo que diría si alguien respondiera. –

+0

Es aún peor con números que comienzan con '+' o '00' ... – viraptor

1

Sería mejor utilizar regular expressions. Un int por definición es solo un número, pero usted desea que los caracteres de formato lo conviertan en un número de teléfono, que es una cadena.

Hay numerosos mensajes sobre la validación del número de teléfono, vea A comprehensive regex for phone number validation para empezar.

+0

He leído mal la pregunta, pero se aplica la misma información. Si * está recibiendo * caracteres adicionales, puede usar expresiones regulares para eliminarlos. Todavía almacenaría el número de teléfono como una cadena, ya que los ceros iniciales que podrían ser una parte válida de un número de teléfono serían eliminados como int. – JYelton

34

Se puede utilizar una expresión regular para eliminar todos los caracteres que no sean dígitos:

string phoneNumber = "(123) 456-7890"; 
phoneNumber = Regex.Replace(phoneNumber, @"[^\d]", ""); 

Luego más adelante - en función de sus necesidades - usted puede guardar el número como una cadena o como un entero. Para convertir el número en un entero de tipo tendrá las siguientes opciones:

// throws if phoneNumber is null or cannot be parsed 
long number = Int64.Parse(phoneNumber, NumberStyles.Integer, CultureInfo.InvariantCulture); 

// same as Int64.Parse, but returns 0 if phoneNumber is null 
number = Convert.ToInt64(phoneNumber); 

// does not throw, but returns true on success 
if (Int64.TryParse(phoneNumber, NumberStyles.Integer, 
     CultureInfo.InvariantCulture, out number)) 
{ 
    // parse was successful 
} 
+8

'[^ \ d]' debe ser el mismo que el '\ D'? –

+2

Sí, es lo mismo. No hace ninguna diferencia, excepto que '[^ \ d]' es más explícito y requiere menos aprendizaje. – Timwi

+4

Tienes que aprender sobre '[^]'. Yo diría que '\ D' requiere menos aprendizaje. – recursive

2

Prueba esto:

string s = "(123) 456-7890"; 
UInt64 i = UInt64.Parse(
    s.Replace("(","") 
    .Replace(")","") 
    .Replace(" ","") 
    .Replace("-","")); 

usted debe estar seguro con esto, ya que se enmascara la entrada.

+0

si el número es '" (543) 231-2322 "' se desbordará 'int32'. –

+0

Buen punto. Reemplazado int con UInt64 –

+0

Te das cuenta de que él en realidad no quiere un número, ¿verdad? El 'int.TryParse' fue solo su conjetura inicial: es una pista falsa. – Gabe

4
string digits = Regex.Replace(formatted, @"\D", String.Empty, RegexOptions.Compiled); 
1

Como ya mencionamos muchas respuestas, primero debe quitar los caracteres que no sean dígitos antes de intentar analizar el número. Puedes hacer esto usando una expresión regular.

Regex.Replace("(123) 456-7890", @"\D", String.Empty) // "1234567890" 

Sin embargo, tenga en cuenta que el valor más grande int positivo puede contener es 2147483647 por lo que cualquier número con un código de área mayor que 214 podría causar un desbordamiento. Es mejor utilizar mucho en esta situación.

Los ceros a la izquierda no serán un problema para los números de América del Norte, ya que los códigos de área no pueden comenzar con cero o uno.

1

Alternativa usando Linq:

string phoneNumber = "(403) 259-7898"; 
var phoneStr = new string(phoneNumber.Where(i=> i >= 48 && i <= 57).ToArray()); 
+3

la parte de "números mágicos" de esta solución debería asustar a todos. –

11

Puesto que nadie hizo un bucle.

long GetPhoneNumber(string PhoneNumberText) 
{ 
    // Returns 0 on error 

    StringBuilder TempPhoneNumber = new StringBuilder(PhoneNumberText.Length); 
    for (int i=0;i<PhoneNumberText.Length;i++) 
    { 
     if (!char.IsDigit(PhoneNumberText[i])) 
      continue; 

     TempPhoneNumber.Append(PhoneNumberText[i]); 
    } 

    PhoneNumberText = TempPhoneNumber.ToString(); 
    if (PhoneNumberText.Length == 0) 
     return 0;// No point trying to parse nothing 

    long PhoneNumber = 0; 
    if(!long.TryParse(PhoneNumberText,out PhoneNumber)) 
     return 0; // Failed to parse string 

    return PhoneNumber; 
} 

utilizarse como esto:

long phoneNumber = GetPhoneNumber("(123) 456-7890"); 


actualización
Como pr comentó muchos países tienen de cero en el inicio de la serie, si tiene que apoyar eso, entonces usted tiene para devolver una cadena no muy larga. Para cambiar mi código para hacer eso, haga lo siguiente:

1) Cambie el tipo de retorno de la función de largo a cadena.
2) Hacer que el nulo retorno de la función en lugar de 0 en caso de error
3) El exitoso analizar hacerlo volver PhoneNumberText

+0

Gracias arreglado. Y sí, esto debería preformarse bien, y debería ser robusto si se analiza la entrada del usuario. – EKS

+1

Está almacenando un número de teléfono. ¿Por qué * siempre * quieres almacenar un número de teléfono como un número entero? – Gabe

+1

Creo que opuesto ... ¿Por qué NO debería almacenarlo como número – EKS

3

Aparte de todas las otras respuestas correctas, el almacenamiento de números de teléfono como números enteros o de otra manera excluyendo formatear puede ser una mala idea.

Aquí hay un par de consideraciones:

  • Los usuarios pueden proporcionar números de teléfono internacionales que no se ajusten a sus expectativas. See these examples Por lo tanto, las agrupaciones habituales para los números estándar de EE. UU. No encajarían.
  • Es posible que los usuarios NECESITAN proporcionar una extensión, por ejemplo, (555) 555-5555 ext#343 La clave # está realmente en el marcador/teléfono, pero no se puede codificar en un número entero. Los usuarios también pueden necesitar suministrar la clave *.
  • Algunos dispositivos le permiten insertar pausas (generalmente con el carácter P), que pueden ser necesarias para extensiones o sistemas de menús, o para marcar en ciertos sistemas telefónicos (por ejemplo, en el extranjero). Estos tampoco pueden codificarse como enteros.

[EDIT]

Podría ser una buena idea para almacenar tanto una versión número entero y una versión de cadena en la base de datos. Además, al almacenar cadenas, puede reducir toda la puntuación a espacios en blanco utilizando uno de los métodos mencionados anteriormente. Una expresión regular para este podría ser:

// (222) 222-2222 ext# 333 -> 222 222 2222 # 333 
phoneString = Regex.Replace(phoneString, @"[^\d#*P]", " "); 

// (222) 222-2222 ext# 333 -> 2222222222333 (information lost) 
phoneNumber = Regex.Replace(phoneString, @"[^\d]", ""); 

// you could try to avoid losing "ext" strings as in (222) 222-2222 ext.333 thus: 
phoneString = Regex.Replace(phoneString, @"ex\w+", "#"); 
phoneString = Regex.Replace(phoneString, @"[^\d#*P]", " "); 
0
public static string DigitsOnly(this string phoneNumber) 
{ 
    return new string(
     new[] 
      { 
      // phoneNumber[0],  (
       phoneNumber[1], // 6 
       phoneNumber[2], // 1 
       phoneNumber[3], // 7 
      // phoneNumber[4], ) 
      // phoneNumber[5], 
       phoneNumber[6], // 8 
       phoneNumber[7], // 6 
       phoneNumber[8], // 7 
      // phoneNumber[9],  - 
       phoneNumber[10], // 5 
       phoneNumber[11], // 3 
       phoneNumber[12], // 0 
       phoneNumber[13] // 9 
      }); 
} 
Cuestiones relacionadas