Encontre e extraia um número de uma sequência


320

Eu tenho um requisito para encontrar e extrair um número contido em uma string.

Por exemplo, a partir dessas strings:

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

Como posso fazer isso?


2
O número pode ser negativo? Em caso afirmativo, como "Olá - como você está? -30" seria tratado?
precisa saber é o seguinte

Olá John, Não há números negativos nos dados
van

4
Números decimais como 1.5? Notação exponencial como 1.5E45?
Tim Pietzcker

Semelhante (mas não idêntico): stackoverflow.com/questions/1561273/…
finnw

3
Por que nenhuma resposta é aceita aqui?
precisa saber é o seguinte

Respostas:


63

passar a corda e 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: Esse código não funciona, resulta com b == "System.Linq.Enumerable..". Correto (e ainda mais simples) seria #b = String.Join("", a.Where(char.IsDigit))
BlueRaja # Danny Pflughoeft 29/05/15

1
Bom ponto, isso vai me ensinar a não testar o código que escrevo no comentário! Você também pode criar uma string a partir de uma matriz de caracteres usando o new string(char[])construtor.
Thomas

1
Regex faz um trabalho muito melhor.
Jason Kelley

@BlueRaja - Danny Pflughoeft Por que não fazer o seu comentário uma resposta adequada para que eu possa votá-lo até :-)
SteveC

NOTA: Se a string contiver vários números, esta resposta os executará todos juntos em um único número. Por exemplo, "a12bcd345" resulta em "12345". (O que pode ser desejável ou não, dependendo da meta.) Isso é diferente da solução Regex mais votada, que retornaria "12" para o caso acima. Isso é importante para casos como números de telefone "555-111-2222".
Página

546

\d+é a regex para um número inteiro. assim

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

retorna uma string contendo a primeira ocorrência de um número em subjectString.

Int32.Parse(resultString) lhe dará o número.


10
para suportar números negativos que você poderia usar em Regex.Match(subjectString, @"-?\d+").Valuevez disso
Jon List

45
Esta resposta não está completa (em C #). Ele está apenas obtendo o primeiro número na string. Você precisa itarar nas correspondências: resultString = string.Join (string.Empty, Regex.Matches (subjectString, @ "\ d +"). OfType <Match> () .Select (m => m.Value));
Markus

8
@ Markus: A pergunta afirma "Eu preciso extrair um número contido em uma string", e todos os exemplos mostram um único número presente na string. A iteração sobre um único item não é útil.
Tim Pietzcker

2
@ayman: Ah, as vírgulas são milhares de separadores? Isso exigirá um regex muito mais complexo - que deve ser tratado em uma pergunta separada. Um excelente ponto de partida é o Regular-Expressions.info, que também contém seções no mecanismo de regex do .NET.
Tim Pietzcker

5
@DavidSopko: Do ​​que você está falando? A pergunta original solicitava uma maneira de extrair um único número de uma sequência, tanto no título quanto no corpo da pergunta. Edições subsequentes à pergunta (um ano após a minha resposta e mais tarde) por outras pessoas que não o autor original mudaram o título para "números". Se alguma coisa, essa edição defeituosa deve ser revertida.
Tim Pietzcker

181

Veja como eu limpo os números de telefone para obter apenas os dígitos:

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

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

1
solução muito elegante .. I como o uso de linq
Leo Gurdian

1
Ótima solução para números inteiros! Esteja ciente de que isso não funcionará se você estiver tentando analisar um número decimal porque o ponto decimal não é um dígito.
Elijah Lofgren

40

use expressão regular ...

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

O que eu uso para obter números de telefone sem pontuação ...

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

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

// result: 7877636511

18

Regex.Split pode extrair números de seqüências de caracteres. Você obtém todos os números encontrados em uma sequência.

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);
    }
}

Resultado:

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


16

Aqui está uma Linqversão:

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

14
que tal simplesmente "123iuow45ss".AsEnumerable().Where(char.IsDigit)?
Ilya Ivanov

2
Eu simplesmente não gosto de from t .. select tredundância, mas de qualquer maneira, aplausos.
Ilya Ivanov

14

Outra solução simples usando o Regex Você deve usar este

using System.Text.RegularExpressions;

e o código é

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

12

Você também pode tentar isso

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

bom, mas se você tiver espaços entre os números na cadeia original, ele fornecerá uma cadeia concatenada grande com os dois números unidos (sem espaço)
Mohammad Zekrallah

11

Basta usar um RegEx para corresponder à string e converter:

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

9

Aqui está outra Linqabordagem que extrai o primeiro número de uma string.

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);

Exemplos:

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

9

Para aqueles que desejam um número decimal a partir de uma string com Regex na linha DUAS :

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

A mesma coisa se aplica a flutuar , longo , 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 é a melhor resposta que me deu o que eu queria, que é uma matriz de vários números na string. Se ao menos pudesse ignorar vírgulas em números (separador de milhar), isso seria perfeito! :-)
Sagar

9

Você pode fazer isso usando a Stringpropriedade como abaixo:

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

que fornece apenas o número da string.


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

7

A pergunta não afirma explicitamente que você deseja apenas os caracteres de 0 a 9, mas não seria exagero acreditar que isso é verdade no seu conjunto de exemplos e comentários. Então, aqui está o código que faz isso.

        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 que você não deseja usar Char.IsDigit () - Os números incluem caracteres como frações, subscritos, sobrescritos, algarismos romanos, numeradores de moeda, números encapsulados e dígitos específicos do script.


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

Obtenha todos os números na string. Portanto, se você usar o exemplo '1 mais 2', ele receberá '12'.


5

Método de extensão para obter todos os números positivos contidos em uma string:

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

Se você também deseja números negativos, modifique esse código para manipular o sinal de menos (- )

Dada esta entrada:

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

A lista de números resultante será:

[1989, 27, 2016]

5

se o número tiver casas decimais, você pode usar abaixo

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 :

"qualquer coisa 876,8 qualquer coisa" ==> 876,8

"qualquer coisa 876 qualquer coisa" ==> 876

"$ 876435" ==> 876435

"$ 876.435" ==> 876.435

Amostra: https://dotnetfiddle.net/IrtqVt


1
Muito obrigado por esta resposta. Estou usando C # e VS2017 e estava tentando descobrir como encontro o valor. Obrigado novamente por sua resposta.
Bubbles


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 é usado para encontrar todo o valor inteiro em uma string.
Manoj Gupta 27/02

Seria melhor adicionar alguma descrição diretamente à resposta do que publicá-la separadamente como um comentário. Os comentários nem sempre são visíveis imediatamente.
John Dvorak

2

Uma abordagem interessante é fornecida aqui por Ahmad Mageed, usa Regex e stringbuilder para extrair os números inteiros na ordem em que eles aparecem na string.

Um exemplo usando o Regex.Split com base na postagem de Ahmad Mageed é o seguinte:

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

Aqui está o meu 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 está a minha solução

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

Você precisará usar o Regex como \d+

\d corresponde aos dígitos na sequência especificada.


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"));

0

Usando @ tim-pietzcker answer acima , o seguinte funcionará PowerShell.

PS C:\> $str = '1 test'
PS C:\> [regex]::match($str,'\d+').value
1

-3

Com base na última amostra, criei um 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;
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.