Encuentra y extrae un número de una cadena


320

Tengo un requisito para encontrar y extraer un número contenido dentro de una cadena.

Por ejemplo, a partir de estas cadenas:

string test = "1 test"
string test1 = " 1 test"
string test2 = "test 99"

¿Cómo puedo hacer esto?


2
¿Podría el número ser negativo? Si es así, ¿cómo se manejaría "Hola, ¿cómo estás? -30"?
Jon Skeet

Hola John, no hay números negativos en los datos
van

44
Números decimales como 1.5? Notación exponencial como 1.5E45?
Tim Pietzcker

Similar (pero no idéntico): stackoverflow.com/questions/1561273/…
finnw

3
¿Por qué no se acepta respuesta aquí?
Wiktor Stribiżew

Respuestas:


63

ir a través de la cuerda y usar Char.IsDigit

string a = "str123";
string b = string.Empty;
int val;

for (int i=0; i< a.Length; i++)
{
    if (Char.IsDigit(a[i]))
        b += a[i];
}

if (b.Length>0)
    val = int.Parse(b);

15
@Thomas: Ese código no funciona, resulta con b == "System.Linq.Enumerable..". Correcto (e incluso más simple) seríab = String.Join("", a.Where(char.IsDigit))
BlueRaja - Danny Pflughoeft

1
Buen punto, ¡eso me enseñará a no probar el código que escribo en el comentario! También puede hacer una cadena de una matriz de caracteres utilizando el new string(char[])constructor.
Thomas

1
Regex hace un trabajo mucho mejor.
Jason Kelley

@BlueRaja - Danny Pflughoeft ¿Por qué no hacer que tu comentario sea una respuesta adecuada para que pueda votarlo
?:

NOTA: Si la cadena contiene varios números, esta respuesta los ejecutará todos juntos en un solo número. Por ejemplo, "a12bcd345" da como resultado "12345". (Lo que puede ser deseable o no, dependiendo del objetivo). Esto es diferente de la solución Regex más votada, que arrojaría "12" para el caso anterior. Esto es importante para casos como los números de teléfono "555-111-2222".
ToolmakerSteve

546

\d+es la expresión regular para un número entero. Entonces

//System.Text.RegularExpressions.Regex
resultString = Regex.Match(subjectString, @"\d+").Value;

devuelve una cadena que contiene la primera aparición de un número en subjectString.

Int32.Parse(resultString) entonces te dará el número.


10
para admitir números negativos que podrías usar Regex.Match(subjectString, @"-?\d+").Valueen su lugar
Jon List

45
Esta respuesta no está completa (en C #). Solo está obteniendo el primer número en la cadena. Debe iterar sobre las coincidencias: resultString = string.Join (string.Empty, Regex.Matches (subjectString, @ "\ d +"). OfType <Match> () .Select (m => m.Value));
Markus

8
@ Markus: La pregunta dice "Necesito extraer un número contenido en una cadena", y todos los ejemplos muestran un solo número presente en la cadena. Iterar sobre un solo elemento no es útil.
Tim Pietzcker

2
@ayman: Oh, ¿las comas son miles de separadores? Eso requerirá una expresión regular mucho más compleja, que debería tratarse en una pregunta separada. Un excelente punto de partida es Regular-Expressions.info, que también contiene secciones en el motor de expresiones regulares de .NET.
Tim Pietzcker

55
@DavidSopko: ¿De qué estás hablando? La pregunta original pedía una forma de extraer un solo número de una cadena, tanto en el título como en el cuerpo de la pregunta. Las ediciones posteriores a la pregunta (un año después de mi respuesta y más tarde) por personas distintas al autor original cambiaron el título a "números". En todo caso, esa edición defectuosa debería revertirse.
Tim Pietzcker

181

Así es como limpio los números de teléfono para obtener solo los dígitos:

string numericPhone = new String(phone.Where(Char.IsDigit).ToArray());

31
string numericPhone =new String(phone.Where(Char.IsDigit).ToArray());
Damith

1
solución muy elegante .. Me gusta el uso de linq
Leo Gurdian

1
¡Buena solución para enteros! Tenga en cuenta que esto no funcionará si está tratando de analizar un número decimal porque el punto decimal no es un dígito.
Elijah Lofgren

40

usar expresiones regulares ...

Regex re = new Regex(@"\d+");
Match m = re.Match("test 66");

if (m.Success)
{
    Console.WriteLine(string.Format("RegEx found " + m.Value + " at position " + m.Index.ToString()));
}
else
{
    Console.WriteLine("You didn't enter a string containing a number!");
}

33

Lo que uso para obtener números de teléfono sin puntuación ...

var phone = "(787) 763-6511";

string.Join("", phone.ToCharArray().Where(Char.IsDigit));

// result: 7877636511

18

Regex.Split puede extraer números de cadenas. Obtienes todos los números que se encuentran en una cadena.

string input = "There are 4 numbers in this string: 40, 30, and 10.";
// Split on one or more non-digit characters.
string[] numbers = Regex.Split(input, @"\D+");
foreach (string value in numbers)
{
    if (!string.IsNullOrEmpty(value))
    {
    int i = int.Parse(value);
    Console.WriteLine("Number: {0}", i);
    }
}

Salida:

Número: 4 Número: 40 Número: 30 Número: 10


16

Aquí hay una Linqversión:

string s = "123iuow45ss";
var getNumbers = (from t in s
                  where char.IsDigit(t)
                  select t).ToArray();
Console.WriteLine(new string(getNumbers));

14
¿qué pasa simplemente "123iuow45ss".AsEnumerable().Where(char.IsDigit)?
Ilya Ivanov

2
Simplemente no me gusta la from t .. select tredundancia, pero de todos modos, aplausos.
Ilya Ivanov

14

Otra solución simple usando Regex Debería necesitar usar esto

using System.Text.RegularExpressions;

y el código es

string var = "Hello3453232wor705Ld";
string mystr = Regex.Replace(var, @"\d", "");
string mynumber = Regex.Replace(var, @"\D", "");
Console.WriteLine(mystr);
Console.WriteLine(mynumber);

12

también puedes probar esto

string.Join(null,System.Text.RegularExpressions.Regex.Split(expr, "[^\\d]"));

bueno, pero si tienes espacios entre los números en la cadena original, entonces te dará 1 cadena concatenada grande con ambos números unidos (sin espacio)
Mohammad Zekrallah

11

Simplemente use un RegEx para que coincida con la cadena, luego convierta:

Match match = Regex.Match(test , @"(\d+)");
if (match.Success) {
   return int.Parse(match.Groups[1].Value);
}

9

Aquí hay otro Linqenfoque que extrae el primer número de una cadena.

string input = "123 foo 456";
int result = 0;
bool success = int.TryParse(new string(input
                     .SkipWhile(x => !char.IsDigit(x))
                     .TakeWhile(x => char.IsDigit(x))
                     .ToArray()), out result);

Ejemplos:

string input = "123 foo 456"; // 123
string input = "foo 456";     // 456
string input = "123 foo";     // 123

9

Para aquellos que desean un número decimal de una cadena con Regex en DOS líneas:

decimal result = 0;
decimal.TryParse(Regex.Match(s, @"\d+").Value, out result);

Lo mismo se aplica al flotador , largo , etc.


9
 string input = "Hello 20, I am 30 and he is 40";
 var numbers = Regex.Matches(input, @"\d+").OfType<Match>().Select(m => int.Parse(m.Value)).ToArray();

1
Esta es la mejor respuesta que me dio lo que quería, que es una matriz de múltiples números dentro de una cadena. Si tan solo pudiera ignorar las comas en números (separador de miles), ¡eso sería perfecto! :-)
Sagar

9

Puede hacer esto usando la Stringpropiedad como a continuación:

 return new String(input.Where(Char.IsDigit).ToArray()); 

que da solo el número de la cadena.


7
var match=Regex.Match(@"a99b",@"\d+");
if(match.Success)
{
    int val;
    if(int.TryParse(match.Value,out val))
    {
        //val is set
    }
}

7

La pregunta no indica explícitamente que solo desea los caracteres del 0 al 9, pero no sería exagerado creer que es cierto a partir de su conjunto de ejemplos y comentarios. Así que aquí está el código que hace eso.

        string digitsOnly = String.Empty;
        foreach (char c in s)
        {
            // Do not use IsDigit as it will include more than the characters 0 through to 9
            if (c >= '0' && c <= '9') digitsOnly += c;
        }

Por qué no desea utilizar Char.IsDigit (): los números incluyen caracteres como fracciones, subíndices, superíndices, números romanos, numeradores de monedas, números encerrados y dígitos específicos de la secuencia de comandos.


6
var outputString = String.Join("", inputString.Where(Char.IsDigit));

Obtenga todos los números en la cadena. Por lo tanto, si utiliza para examaple '1 plus 2' obtendrá '12'.


5

Método de extensión para obtener todos los números positivos contenidos en una cadena:

    public static List<long> Numbers(this string str)
    {
        var nums = new List<long>();
        var start = -1;
        for (int i = 0; i < str.Length; i++)
        {
            if (start < 0 && Char.IsDigit(str[i]))
            {
                start = i;
            }
            else if (start >= 0 && !Char.IsDigit(str[i]))
            {
                nums.Add(long.Parse(str.Substring(start, i - start)));
                start = -1;
            }
        }
        if (start >= 0)
            nums.Add(long.Parse(str.Substring(start, str.Length - start)));
        return nums;
    }

Si también desea números negativos, simplemente modifique este código para manejar el signo menos ( -)

Dada esta entrada:

"I was born in 1989, 27 years ago from now (2016)"

La lista de números resultante será:

[1989, 27, 2016]

5

si el número tiene puntos decimales, puede usar a continuación

using System;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
            //Your code goes here
            Console.WriteLine(Regex.Match("anything 876.8 anything", @"\d+\.*\d*").Value);
            Console.WriteLine(Regex.Match("anything 876 anything", @"\d+\.*\d*").Value);
            Console.WriteLine(Regex.Match("$876435", @"\d+\.*\d*").Value);
            Console.WriteLine(Regex.Match("$876.435", @"\d+\.*\d*").Value);
        }
    }
}

resultados:

"anything 876.8 anything" ==> 876.8

"anything 876 anything" ==> 876

"$ 876435" ==> 876435

"$ 876.435" ==> 876.435

Muestra: https://dotnetfiddle.net/IrtqVt


1
Muchas gracias por esta respuesta. Estoy usando C # y VS2017 y estaba tratando de descubrir cómo encuentro el valor. Gracias de nuevo por tu respuesta.
Burbujas


2
  string verificationCode ="dmdsnjds5344gfgk65585";
            string code = "";
            Regex r1 = new Regex("\\d+");
          Match m1 = r1.Match(verificationCode);
           while (m1.Success)
            {
                code += m1.Value;
                m1 = m1.NextMatch();
            }

Este código se usa para encontrar todos los valores enteros en una cadena.
Manoj Gupta

Sería mejor agregar alguna descripción directamente en la respuesta que publicarla por separado como comentario. Los comentarios no siempre son visibles de inmediato.
John Dvorak

2

Aquí se proporciona un enfoque interesante por Ahmad Mageed, utiliza expresiones regulares y StringBuilder para extraer los números enteros en el orden en que aparecen en la cadena.

Un ejemplo de uso de Regex.Split basado en la publicación de Ahmad Mageed es el siguiente:

var dateText = "MARCH-14-Tue";
string splitPattern = @"[^\d]";
string[] result = Regex.Split(dateText, splitPattern);
var finalresult = string.Join("", result.Where(e => !String.IsNullOrEmpty(e)));
int DayDateInt = 0;

int.TryParse(finalresult, out DayDateInt);

2

Aquí está mi algoritmo

    //Fast, C Language friendly
    public static int GetNumber(string Text)
    {
        int val = 0;
        for(int i = 0; i < Text.Length; i++)
        {
            char c = Text[i];
            if (c >= '0' && c <= '9')
            {
                val *= 10;
                //(ASCII code reference)
                val += c - 48;
            }
        }
        return val;
    }

1

aqui esta mi solucion

string var = "Hello345wor705Ld";
string alpha = string.Empty;
string numer = string.Empty;
foreach (char str in var)
{
    if (char.IsDigit(str))
        numer += str.ToString();
    else
        alpha += str.ToString();
}
Console.WriteLine("String is: " + alpha);
Console.WriteLine("Numeric character is: " + numer);
Console.Read();


0
static string GetdigitFromString(string str)
    {
        char[] refArray = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
        char[] inputArray = str.ToCharArray();
        string ext = string.Empty;
        foreach (char item in inputArray)
        {
            if (refArray.Contains(item))
            {
                ext += item.ToString();
            }
        }
        return ext;
    }

0
string s = "kg g L000145.50\r\n";
        char theCharacter = '.';
        var getNumbers = (from t in s
                          where char.IsDigit(t) || t.Equals(theCharacter)
                          select t).ToArray();
        var _str = string.Empty;
        foreach (var item in getNumbers)
        {
            _str += item.ToString();
        }
        double _dou = Convert.ToDouble(_str);
        MessageBox.Show(_dou.ToString("#,##0.00"));


-3

Basado en la última muestra, creé un método:

private string GetNumberFromString(string sLongString, int iLimitNumbers)
{
    string sReturn = "NA";
    int iNumbersCounter = 0;
    int iCharCounter = 0; 

    string sAlphaChars = string.Empty;
    string sNumbers = string.Empty;
    foreach (char str in sLongString)
    {
        if (char.IsDigit(str))
        {
            sNumbers += str.ToString();
            iNumbersCounter++;
            if (iNumbersCounter == iLimitNumbers)
            {
                return sReturn = sNumbers;
            }
        }
        else
        {
            sAlphaChars += str.ToString();
            iCharCounter++;
            // reset the counter 
            iNumbersCounter = 0; 
        }
    }
    return sReturn;
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.