Probablemente debería utilizar en IsDigitlugar de IsNumber: "Este método [ IsNumber] determina si a Charpertenece a alguna categoría numérica Unicode. Además de incluir dígitos, los números incluyen caracteres, fracciones, subíndices, superíndices, números romanos, numeradores de moneda y números entre círculos. Este método contrasta con el IsDigitmétodo, que determina si a Chares un dígito de base 10 ". msdn.microsoft.com/en-us/library/yk2b3t2y.aspx
LukeH
2
@TrevorBrooks Supongamos que puede ampliar los términos:input.Where(c => char.IsDigit(c) || char.IsWhiteSpace(c))
Fredrik Mörk
6
Se puede simplificar aún más return new string(input.Where(char.IsDigit).ToArray());. Simplemente lo hago más legible
Zapnologica
2
Buena respuesta. Es posible que solo desee considerar cambiar el nombre de la función de 'GetNumbers' a 'GetDigits' también ... para dejar clara su intención.
JTech
2
También es un gran método de extensión.
Roberto Bonini
61
Se siente como una buena opción para una expresión regular.
var s ="40,595 p.a.";var stripped =Regex.Replace(s,"[^0-9]","");
"[^0-9]"puede ser reemplazado por @"\D"pero me gusta la legibilidad de [^0-9].
Estoy de acuerdo siempre que esté de acuerdo con la sobrecarga asociada con las expresiones regulares en .Net
FrankO
4
Por curiosidad, ¿cuál es el rendimiento general entre esta respuesta y la respuesta de Fredrik Mork?
Scuba Steve
Probablemente esto sea más lento, pero la única forma de saberlo es medir porque depende de cómo .NET implementa las expresiones regulares, cómo se compila la expresión Lambda y más.
Jonas Elfström
1
Esto es más flexible que usar IsDigit (), ya que puede agregar '.' caracteres a la expresión regular si desea permitir números con posiciones decimales.
Richard Moore
10
Hice una comparación simple de Regex versus LINQ en una cadena construida a partir de 100,000 GUID unidos (lo que resultó en una cadena de caracteres de 3,600,000). Regex fue consistentemente alrededor de medio segundo, mientras que LINQ estuvo consistentemente en el rango de 1/10 de segundo. Básicamente, LINQ fue 5 veces más rápido en promedio.
Chris Pratt
8
Un método de extensión será un mejor enfoque:
publicstaticstringGetNumbers(thisstring text){
text = text ??string.Empty;returnnewstring(text.Where(p =>char.IsDigit(p)).ToArray());}
Prefiero if (text == null) return string.Empty;más text = text ?? string.Empty;. De esta forma no disminuimos el rendimiento.
Hooman
6
Use una expresión regular que solo capture 0-9 y descarte el resto. Sin embargo, una expresión regular es una operación que va a costar mucho la primera vez. O haz algo como esto:
var sb =newStringBuilder();var goodChars ="0123456789".ToCharArray();var input ="40,595";foreach(var c in input){if(goodChars.IndexOf(c)>=0)
sb.Append(c);}var output = sb.ToString();
¿Qué pasa con el negativo? (-) ¿No debería ser menos parte de esto?
Seabizkit
0
Bueno, ya sabes cuáles son los dígitos: 0123456789, ¿verdad? Atraviesa tu cadena carácter por carácter; si el carácter es un dígito, colóquelo al final de una cadena temporal, de lo contrario ignórelo. Puede haber otros métodos auxiliares disponibles para cadenas de C #, pero este es un enfoque genérico que funciona en todas partes.
¿Qué debo hacer para que Regex funcione y obtenga este error? El nombre 'Regex' no existe en el contexto actual
StevieB
utilizando System.Text.RegularExpressions;
dhirschl
0
La respuesta aceptada es excelente, sin embargo, no tiene en cuenta los valores NULL, por lo que es inutilizable en la mayoría de los escenarios.
Esto me llevó a usar estos métodos auxiliares en su lugar. El primero responde al OP, mientras que los otros pueden ser útiles para quienes quieran realizar lo contrario:
/// <summary>/// Strips out non-numeric characters in string, returning only digits/// ref.: /programming/3977497/stripping-out-non-numeric-characters-in-string/// </summary>/// <param name="input">the input string</param>/// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>/// <returns>the input string numeric part: for example, if input is "XYZ1234A5U6" it will return "123456"</returns>publicstaticstringGetNumbers(string input,bool throwExceptionIfNull =false){return(input ==null&&!throwExceptionIfNull)? input
:newstring(input.Where(c =>char.IsDigit(c)).ToArray());}/// <summary>/// Strips out numeric and special characters in string, returning only letters/// </summary>/// <param name="input">the input string</param>/// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>/// <returns>the letters contained within the input string: for example, if input is "XYZ1234A5U6~()" it will return "XYZAU"</returns>publicstaticstringGetLetters(string input,bool throwExceptionIfNull =false){return(input ==null&&!throwExceptionIfNull)? input
:newstring(input.Where(c =>char.IsLetter(c)).ToArray());}/// <summary>/// Strips out any non-numeric/non-digit character in string, returning only letters and numbers/// </summary>/// <param name="input">the input string</param>/// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>/// <returns>the letters contained within the input string: for example, if input is "XYZ1234A5U6~()" it will return "XYZ1234A5U6"</returns>publicstaticstringGetLettersAndNumbers(string input,bool throwExceptionIfNull =false){return(input ==null&&!throwExceptionIfNull)? input
:newstring(input.Where(c =>char.IsLetterOrDigit(c)).ToArray());}
Respuestas:
Hay muchas formas, pero esto debería funcionar (aunque no sé cómo funciona con cadenas realmente grandes):
fuente
IsDigit
lugar deIsNumber
: "Este método [IsNumber
] determina si aChar
pertenece a alguna categoría numérica Unicode. Además de incluir dígitos, los números incluyen caracteres, fracciones, subíndices, superíndices, números romanos, numeradores de moneda y números entre círculos. Este método contrasta con elIsDigit
método, que determina si aChar
es un dígito de base 10 ". msdn.microsoft.com/en-us/library/yk2b3t2y.aspxinput.Where(c => char.IsDigit(c) || char.IsWhiteSpace(c))
return new string(input.Where(char.IsDigit).ToArray());
. Simplemente lo hago más legibleSe siente como una buena opción para una expresión regular.
"[^0-9]"
puede ser reemplazado por@"\D"
pero me gusta la legibilidad de[^0-9]
.fuente
Un método de extensión será un mejor enfoque:
fuente
if (text == null) return string.Empty;
mástext = text ?? string.Empty;
. De esta forma no disminuimos el rendimiento.Use una expresión regular que solo capture 0-9 y descarte el resto. Sin embargo, una expresión regular es una operación que va a costar mucho la primera vez. O haz algo como esto:
Creo que algo así, aunque no lo he compilado ...
LINQ es, como dijo Fredrik, también una opción
fuente
Otra opción ...
fuente
Bueno, ya sabes cuáles son los dígitos: 0123456789, ¿verdad? Atraviesa tu cadena carácter por carácter; si el carácter es un dígito, colóquelo al final de una cadena temporal, de lo contrario ignórelo. Puede haber otros métodos auxiliares disponibles para cadenas de C #, pero este es un enfoque genérico que funciona en todas partes.
fuente
Aquí está el código que usa expresiones regulares:
fuente
La respuesta aceptada es excelente, sin embargo, no tiene en cuenta los valores NULL, por lo que es inutilizable en la mayoría de los escenarios.
Esto me llevó a usar estos métodos auxiliares en su lugar. El primero responde al OP, mientras que los otros pueden ser útiles para quienes quieran realizar lo contrario:
Para obtener información adicional, lea esta publicación en mi blog.
fuente
fuente
fuente