Suchen und extrahieren Sie eine Zahl aus einer Zeichenfolge

319

Ich muss eine in einer Zeichenfolge enthaltene Zahl finden und extrahieren.

Zum Beispiel aus diesen Zeichenfolgen:

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

Wie kann ich das machen?

van
quelle
2
Könnte die Zahl negativ sein? Wenn ja, wie würde "Hallo - wie geht es dir? -30" behandelt?
Jon Skeet
Hallo John, keine negativen Zahlen in den Daten
van
4
Dezimalzahlen wie 1.5? Exponentielle Notation wie 1.5E45?
Tim Pietzcker
Ähnlich (aber nicht identisch): stackoverflow.com/questions/1561273/…
finnw
3
Warum wird hier keine Antwort akzeptiert?
Wiktor Stribiżew

Antworten:

63

gehe durch die Schnur und benutze 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
quelle
15
@Thomas: Dieser Code funktioniert nicht, er ergibt sich mit b == "System.Linq.Enumerable..". Richtig (und noch einfacher) wäreb = String.Join("", a.Where(char.IsDigit))
BlueRaja - Danny Pflughoeft
1
Guter Punkt, das wird mich lehren, den Code, den ich in einem Kommentar schreibe, nicht zu testen! Sie können mit dem new string(char[])Konstruktor auch eine Zeichenfolge aus einem char-Array erstellen .
Thomas
1
Regex macht einen viel besseren Job.
Jason Kelley
@ BlueRaja - Danny Pflughoeft Warum nicht Ihren Kommentar zu einer richtigen Antwort machen, damit ich darüber abstimmen kann :-)
SteveC
HINWEIS: Wenn die Zeichenfolge mehrere Zahlen enthält, werden sie bei dieser Antwort alle zu einer einzigen Zahl zusammengefasst. Beispielsweise führt "a12bcd345" zu "12345". (Was je nach Ziel wünschenswert oder nicht wünschenswert sein kann.) Dies unterscheidet sich von der am besten bewerteten Regex-Lösung, die für den obigen Fall "12" zurückgeben würde. Dies ist wichtig für Fälle wie die Telefonnummern "555-111-2222".
ToolmakerSteve
546

\d+ist der reguläre Ausdruck für eine Ganzzahl. Damit

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

Gibt eine Zeichenfolge zurück, die das erste Vorkommen einer Zahl in enthält subjectString.

Int32.Parse(resultString) wird Ihnen dann die Nummer geben.

Tim Pietzcker
quelle
10
um negative Zahlen zu unterstützen, könnten Sie Regex.Match(subjectString, @"-?\d+").Valuestattdessen verwenden
Jon List
45
Diese Antwort ist nicht vollständig (in C #). Es wird nur die erste Zahl in der Zeichenfolge abgerufen. Sie müssen die Übereinstimmungen durchlaufen: resultString = string.Join (string.Empty, Regex.Matches (subjectString, @ "\ d +"). OfType <Match> () .Select (m => m.Value));
Markus
8
@Markus: Die Frage lautet "Ich muss eine in einer Zeichenfolge enthaltene Zahl extrahieren ", und alle Beispiele zeigen, dass eine einzelne Zahl in der Zeichenfolge vorhanden ist. Das Iterieren über ein einzelnes Element ist nicht sinnvoll.
Tim Pietzcker
2
@ayman: Oh, die Kommas sind Tausende Trennzeichen? Dies erfordert eine viel komplexere Regex - die in einer separaten Frage behandelt werden sollte. Ein ausgezeichneter Ausgangspunkt ist Regular-Expressions.info, das auch Abschnitte zur Regex-Engine von .NET enthält.
Tim Pietzcker
5
@ DavidSopko: Worüber sprichst du? In der ursprünglichen Frage wurde nach einer Möglichkeit gefragt, eine einzelne Zahl aus einer Zeichenfolge zu extrahieren, sowohl im Titel als auch im Fragentext. Nachfolgende Änderungen an der Frage (ein Jahr nach meiner Antwort und später) durch andere Personen als den ursprünglichen Autor haben den Titel in "Zahlen" geändert. Wenn überhaupt, sollte diese fehlerhafte Bearbeitung zurückgesetzt werden.
Tim Pietzcker
180

So bereinige ich Telefonnummern, um nur die Ziffern zu erhalten:

string numericPhone = new String(phone.Where(Char.IsDigit).ToArray());
Dave
quelle
31
string numericPhone =new String(phone.Where(Char.IsDigit).ToArray());
Damith
1
sehr elegante Lösung .. Ich mag die Verwendung von linq
Leo Gurdian
1
Gute Lösung für ganze Zahlen! Beachten Sie, dass dies nicht funktioniert, wenn Sie versuchen, eine Dezimalzahl zu analysieren, da der Dezimalpunkt keine Ziffer ist.
Elijah Lofgren
40

Verwenden Sie reguläre Ausdrücke ...

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
quelle
33

Was ich benutze, um Telefonnummern ohne Interpunktion zu erhalten ...

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

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

// result: 7877636511
ejcortes
quelle
18

Regex.Split kann Zahlen aus Zeichenfolgen extrahieren. Sie erhalten alle Zahlen, die in einer Zeichenfolge gefunden werden.

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

Ausgabe:

Nummer: 4 Nummer: 40 Nummer: 30 Nummer: 10

Tabares
quelle
16

Hier ist eine LinqVersion:

string s = "123iuow45ss";
var getNumbers = (from t in s
                  where char.IsDigit(t)
                  select t).ToArray();
Console.WriteLine(new string(getNumbers));
spajce
quelle
14
was ist einfach "123iuow45ss".AsEnumerable().Where(char.IsDigit)?
Ilya Ivanov
2
Ich mag from t .. select tRedundanz einfach nicht , aber trotzdem, Prost.
Ilya Ivanov
13

Eine weitere einfache Lösung mit Regex Sie sollten diese verwenden müssen

using System.Text.RegularExpressions;

und der Code ist

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

quelle
13

Sie können dies auch versuchen

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

Verwenden Sie einfach ein RegEx, um die Zeichenfolge abzugleichen, und konvertieren Sie dann:

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

Hier ist ein anderer LinqAnsatz, der die erste Zahl aus einer Zeichenfolge extrahiert.

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

Beispiele:

string input = "123 foo 456"; // 123
string input = "foo 456";     // 456
string input = "123 foo";     // 123
Fubo
quelle
9

Für diejenigen, die eine Dezimalzahl aus einer Zeichenfolge mit Regex in ZWEI Zeilen wünschen :

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

Gleiches gilt für Float , Long , etc ...

Richard Fu
quelle
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
quelle
1
Dies ist die beste Antwort, die mir das gab, was ich wollte, nämlich ein Array mit mehreren Zahlen innerhalb einer Zeichenfolge. Wenn es nur Kommas in Zahlen (Tausendertrennzeichen) ignorieren könnte, wäre das perfekt! :-)
Sagar
9

Sie können dies mit der folgenden StringEigenschaft tun :

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

Das gibt nur die Nummer aus der Zeichenfolge.

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

Die Frage besagt nicht explizit, dass Sie nur die Zeichen 0 bis 9 möchten, aber es wäre nicht schwer zu glauben, dass dies anhand Ihres Beispielsatzes und Ihrer Kommentare zutrifft. Hier ist also der Code, der das macht.

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

Warum Sie Char.IsDigit () nicht verwenden möchten - Zahlen enthalten Zeichen wie Brüche, Indizes, hochgestellte Zeichen, römische Ziffern, Währungszähler, eingekreiste Zahlen und skriptspezifische Ziffern.

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

Holen Sie sich alle Zahlen in der Zeichenfolge. Wenn Sie also zum Beispiel '1 plus 2' verwenden, wird '12' angezeigt.

Tom
quelle
5

Erweiterungsmethode, um alle positiven Zahlen in einer Zeichenfolge abzurufen:

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

Wenn Sie auch negative Zahlen möchten, ändern Sie diesen Code einfach, um das Minuszeichen zu verarbeiten (- ) zu verarbeiten.

Angesichts dieser Eingabe:

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

Die resultierende Zahlenliste lautet:

[1989, 27, 2016]
Thomas CG de Vilhena
quelle
5

Wenn die Zahl Dezimalstellen hat, können Sie diese unten verwenden

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

Ergebnisse :

"alles 876.8 alles" ==> 876.8

"irgendetwas 876 irgendetwas" ==> 876

"$ 876435" ==> 876435

"$ 876.435" ==> 876.435

Beispiel: https://dotnetfiddle.net/IrtqVt

Tarek El-Mallah
quelle
1
Vielen Dank für diese Antwort. Ich verwende C # und VS2017 und habe versucht herauszufinden, wie ich den Wert finde. Nochmals vielen Dank für Ihre Antwort.
Bubbles
3

Hat sich eine der Antworten auf diese Frage umgekehrt: Wie entferne ich Zahlen mit Regex.Replace aus der Zeichenfolge?

// 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
quelle
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
quelle
Dieser Code wird verwendet, um alle ganzzahligen Werte in einer Zeichenfolge zu finden.
Manoj Gupta
Es wäre besser, eine Beschreibung direkt in die Antwort einzufügen, als sie separat als Kommentar zu veröffentlichen. Kommentare sind nicht immer sofort sichtbar.
John Dvorak
2

Ein interessanter Ansatz wird hier von Ahmad Mageed bereitgestellt, der Regex und Stringbuilder verwendet, um die Ganzzahlen in der Reihenfolge zu extrahieren, in der sie in der Zeichenfolge erscheinen.

Ein Beispiel für die Verwendung von Regex.Split basierend auf dem Beitrag von Ahmad Mageed lautet wie folgt:

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
quelle
2

Hier ist mein Algorithmus

    //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
quelle
1

Hier ist meine Lösung

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

quelle
0

Sie müssen Regex als verwenden \d+

\d stimmt mit den Ziffern in der angegebenen Zeichenfolge überein.

Sachin Shanbhag
quelle
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 Anfänger
quelle
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
quelle
0

Wenn Sie die Antwort von @ tim-pietzcker von oben verwenden , funktioniert Folgendes PowerShell.

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

Basierend auf dem letzten Beispiel habe ich eine Methode erstellt:

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
quelle