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?

furgão
fonte
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);
Sasha Reminnyi
fonte
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.

Tim Pietzcker
fonte
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());
Dave
fonte
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!");
}
Pranay Rana
fonte
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
ejcortes
fonte
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

Tabares
fonte
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));
spajce
fonte
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);

fonte
12

Você também pode tentar isso

string.Join(null,System.Text.RegularExpressions.Regex.Split(expr, "[^\\d]"));
BvdVen
fonte
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);
}
Daniel Gehriger
fonte
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
fubo
fonte
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 ...

Richard Fu
fonte
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();
Ramireddy Ambati
fonte
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.

Shyam sundar shah
fonte
7
var match=Regex.Match(@"a99b",@"\d+");
if(match.Success)
{
    int val;
    if(int.TryParse(match.Value,out val))
    {
        //val is set
    }
}
gastador
fonte
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.

Atters
fonte
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'.

Tom
fonte
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]
Thomas CG de Vilhena
fonte
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

Tarek El-Mallah
fonte
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
3

O inverso de uma das respostas para esta pergunta: Como remover números da string usando o Regex.Replace?

// Pull out only the numbers from the string using LINQ

var numbersFromString = new String(input.Where(x => x >= '0' && x <= '9').ToArray());

var numericVal = Int32.Parse(numbersFromString);
mwilly
fonte
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();
            }
Manoj Gupta
fonte
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);
Simba
fonte
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;
    }
HS_Kernel
fonte
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();

fonte
0

Você precisará usar o Regex como \d+

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

Sachin Shanbhag
fonte
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;
    }
Ruby Beginner
fonte
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"));
watcharachai unvijit
fonte
0

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

PS C:\> $str = '1 test'
PS C:\> [regex]::match($str,'\d+').value
1
user2320464
fonte
-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;
}
MrJTNY
fonte