Trova ed estrai un numero da una stringa


320

Ho l'obbligo di trovare ed estrarre un numero contenuto in una stringa.

Ad esempio, da queste stringhe:

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

Come posso fare questo?


2
Il numero potrebbe essere negativo? In tal caso, come verrebbe gestito "Ciao - come stai? -30"?
Jon Skeet,

Ciao John, nessun numero negativo nei dati
van

4
Numeri decimali come 1.5? Notazione esponenziale come 1.5E45?
Tim Pietzcker,

Simile (ma non identico): stackoverflow.com/questions/1561273/...
finnw

3
Perché nessuna risposta è accettata qui?
Wiktor Stribiżew,

Risposte:


63

passare attraverso la stringa e utilizzare 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: quel codice non funziona, risulta b == "System.Linq.Enumerable..". Corretto (e ancora più semplice) sarebbeb = String.Join("", a.Where(char.IsDigit))
BlueRaja - Danny Pflughoeft

1
Bene, questo mi insegnerà a non testare il codice che scrivo nei commenti! Puoi anche creare una stringa da un array di caratteri usando il new string(char[])costruttore.
Thomas,

1
Regex fa un lavoro molto migliore.
Jason Kelley l'

@BlueRaja - Danny Pflughoeft Perché non rendere il tuo commento una risposta adeguata in modo che io possa votarlo :-)
SteveC

NOTA: se la stringa contiene più numeri, questa risposta li eseguirà tutti insieme in un unico numero. Ad esempio "a12bcd345" genera "12345". (Che può essere desiderabile o no, a seconda dell'obiettivo.) Questo è diverso dalla soluzione Regex più votata, che restituirebbe "12" per il caso sopra. Questo è importante per casi come i numeri di telefono "555-111-2222".
ToolmakerSteve

546

\d+è la regex per un numero intero. Così

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

restituisce una stringa contenente la prima occorrenza di un numero in subjectString.

Int32.Parse(resultString) ti darà quindi il numero.


10
per supportare i numeri negativi che potresti usare Regex.Match(subjectString, @"-?\d+").Valueinvece
Jon List,

45
Questa risposta non è completa (in C #). Sta solo ottenendo il primo numero nella stringa. Devi separare le partite: resultString = string.Join (string.Empty, Regex.Matches (subjectString, @ "\ d +"). OfType <Match> () .Select (m => m.Value));
Markus,

8
@Markus: la domanda afferma "Ho bisogno di estrarre un numero contenuto in una stringa", e tutti gli esempi mostrano un singolo numero presente nella stringa. Iterare su un singolo elemento non è utile.
Tim Pietzcker,

2
@ayman: Oh, le virgole sono migliaia di separatori? Ciò richiederà una regex molto più complessa, che dovrebbe essere trattata in una domanda separata. Un eccellente punto di partenza è Regular-Expressions.info che contiene anche sezioni sul motore regex di .NET.
Tim Pietzcker,

5
@DavidSopko: di cosa stai parlando? La domanda originale chiedeva un modo per estrarre un singolo numero da una stringa, sia nel titolo che nel corpo della domanda. Le successive modifiche alla domanda (un anno dopo la mia risposta e successive) da parte di persone diverse dall'autore originale hanno cambiato il titolo in "numeri". Semmai, quella modifica difettosa dovrebbe essere ripristinata.
Tim Pietzcker,

181

Ecco come pulisco i numeri di telefono per ottenere solo le cifre:

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

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

1
soluzione molto elegante .. Mi piace l'uso di linq
Leo Gurdian,

1
Bella soluzione per numeri interi! Tieni presente che questo non funzionerà se stai cercando di analizzare un numero decimale perché il punto decimale non è una cifra.
Elia Lofgren,

40

usa espressione regolare ...

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

Quello che uso per ottenere i numeri di telefono senza punteggiatura ...

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

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

// result: 7877636511

18

Regex.Split può estrarre numeri da stringhe. Ottieni tutti i numeri che si trovano in una stringa.

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

Produzione:

Numero: 4 Numero: 40 Numero: 30 Numero: 10


16

Ecco una Linqversione:

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

14
che dire semplicemente "123iuow45ss".AsEnumerable().Where(char.IsDigit)?
Ilya Ivanov,

2
Semplicemente non mi piace la from t .. select tridondanza, ma comunque, evviva.
Ilya Ivanov,

14

Un'altra semplice soluzione che utilizza Regex Dovresti usare questo

using System.Text.RegularExpressions;

e il codice è

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

12

Puoi anche provare questo

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

bello ma se hai spazi tra i numeri nella stringa originale allora ti darà 1 grande stringa concatenata con entrambi i numeri uniti (nessuno spazio)
Mohammad Zekrallah,

11

Basta usare un RegEx per abbinare la stringa, quindi convertire:

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

9

Ecco un altro Linqapproccio che estrae il primo numero da una stringa.

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

Esempi:

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

9

Per coloro che desiderano un numero decimale da una stringa con Regex in DUE righe:

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

La stessa cosa vale per float , long , ecc ...


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
Questa è la risposta migliore che mi ha dato quello che volevo, ovvero una matrice di più numeri all'interno della stringa. Se solo potesse ignorare le virgole in numeri (migliaia di separatori), allora sarebbe perfetto! :-)
Sagar,

9

Puoi farlo usando la Stringproprietà come sotto:

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

che fornisce solo un numero dalla stringa.


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

7

La domanda non afferma esplicitamente che vuoi solo i caratteri da 0 a 9, ma non sarebbe difficile credere che sia vero dal tuo esempio e dai tuoi commenti. Quindi ecco il codice che lo fa.

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

Perché non vuoi usare Char.IsDigit () - I numeri includono caratteri come frazioni, pedici, apici, numeri romani, numeratori di valuta, numeri cerchiati e cifre specifiche dello script.


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

Ottieni tutti i numeri nella stringa. Quindi se usi per l'esempio '1 più 2' otterrai '12'.


5

Metodo di estensione per ottenere tutti i numeri positivi contenuti in una stringa:

    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 vuoi anche numeri negativi, modifica semplicemente questo codice per gestire il segno meno ( -)

Dato questo input:

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

L'elenco dei numeri risultanti sarà:

[1989, 27, 2016]

5

se il numero ha un punto decimale, puoi usare di seguito

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

risultati:

"nulla 876,8 nulla" ==> 876,8

"nulla 876 niente" ==> 876

"$ 876435" ==> 876435

"$ 876.435" ==> 876.435

Esempio: https://dotnetfiddle.net/IrtqVt


1
Grazie mille per questa risposta Sto usando C # e VS2017 e stavo cercando di capire come trovo il valore. Grazie ancora per la tua risposta
Bolle il


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

Questo codice viene utilizzato per trovare tutto il valore intero in una stringa.
Manoj Gupta,

Sarebbe meglio aggiungere una descrizione direttamente nella risposta piuttosto che pubblicarla separatamente come commento. I commenti non sono sempre immediatamente visibili.
John Dvorak,

2

Ahmad Mageed fornisce qui un approccio interessante , usa Regex e stringbuilder per estrarre gli interi nell'ordine in cui appaiono nella stringa.

Un esempio che utilizza Regex.Split basato sul post di Ahmad Mageed è il seguente:

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

Ecco il mio 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

ecco la mia soluzione

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

Dovrai utilizzare Regex come \d+

\d corrisponde alle cifre nella stringa specificata.


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

Sulla base dell'ultimo esempio ho creato un metodo:

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;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.