Знайдіть і витягніть число з рядка


319

У мене є вимога знайти і витягти число, що міститься в рядку.

Наприклад, із цих рядків:

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

Як я можу це зробити?


2
Чи може число бути від’ємним? Якщо так, як би "Привіт - як у вас? -30"?
Джон Скіт

Привіт Джон, не сподобалося чисел в даних
ван

4
Десяткові числа, як 1.5? Експоненціальні позначення типу 1.5E45?
Тім Піцкер

Аналогічна (але не ідентичні): stackoverflow.com/questions/1561273 / ...
finnw

3
Чому тут не приймається відповідь?
Wiktor Stribiżew

Відповіді:


63

пройти через рядок і використовувати 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: Цей код не працює, він призводить до b == "System.Linq.Enumerable..". Правильно (і навіть простіше) було бb = String.Join("", a.Where(char.IsDigit))
BlueRaja - Danny Pflughoeft

1
Добре, що я навчу не тестувати код, про який пишу в коментарі! Ви також можете зробити рядок із масиву char за допомогою new string(char[])конструктора.
Томас

1
Regex робить набагато кращу роботу.
Джейсон Келлі

@BlueRaja - Danny Pflughoeft Чому б не зробити ваш коментар правильною відповіддю, щоб я міг його проголосувати :-)
SteveC

ПРИМІТКА. Якщо рядок містить декілька чисел, ця відповідь об'єднає їх усі в одне число. Наприклад, "a12bcd345" призводить до "12345". (Що може бути бажано чи ні, залежно від поставленої мети.) Це відрізняється від рішення, яке голосує Regex, яке б повернуло "12" для вищевикладеного випадку. Це має значення для таких випадків, як номери телефонів "555-111-2222".
ToolmakerSteve

546

\d+- це регулярне вираження для цілого числа. Тому

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

повертає рядок, що містить перший вхід числа у subjectString.

Int32.Parse(resultString) то дасть вам номер.


10
щоб підтримувати негативні числа, які ви могли використовувати Regex.Match(subjectString, @"-?\d+").Valueзамість цього
Jon List

45
Ця відповідь не є повною (в C #). Це лише отримання першого числа в рядку. Ви повинні розміщувати файли відповідності: resultString = string.Join (string.Empty, Regex.Matches (subjectString, @ "\ d +"). OfType <Match> () .Select (m => m.Value));
Маркус

8
@Markus: питання свідчить : «Мені потрібно витягти номер , що міститься в рядку», і все приклади показують одне число присутній в рядку. Ітерація над одним елементом не корисна.
Тім Піцкер

2
@ayman: О, коми - це тисячі роздільників? Для цього знадобиться набагато складніший вираз, - який слід вирішити в окремому питанні. Відмінною відправною точкою є Regular-Expressions.info, який також містить розділи про регекс-движок .NET.
Тім Піцкер

5
@DavidSopko: Про що ти говориш? В оригінальному запитанні було запропоновано спосіб витягти одне число з рядка, як у заголовку, так і в тілі запитання. Подальші редагування питання (через рік після моєї відповіді та пізніше) іншими людьми, ніж оригінальний автор, змінили заголовок на "цифри". Якщо що-небудь, це несправне редагування слід відмовити.
Тім Піцкер

180

Ось як я очищую телефонні номери, щоб отримати лише цифри:

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

31
string numericPhone =new String(phone.Where(Char.IsDigit).ToArray());
Деміт

1
дуже елегантне рішення .. Мені подобається використання linq
Лев Гурдян

1
Гарне рішення для цілих чисел! Пам’ятайте, що це не спрацює, якщо ви намагаєтеся розібрати десятковий номер, оскільки десяткова крапка не є цифрою.
Ілля

40

використовувати регулярний вираз ...

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

Що я використовую для отримання номерів телефонів без розділових знаків ...

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

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

// result: 7877636511

18

Regex.Split може витягувати числа з рядків. Ви отримуєте всі числа, які знаходяться в рядку.

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

Вихід:

Число: 4 Число: 40 Число: 30 Число: 10


16

Ось Linqверсія:

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

14
а як просто "123iuow45ss".AsEnumerable().Where(char.IsDigit)?
Ілля Іванов

2
Я просто не люблю from t .. select tнадмірності, але все одно, ура.
Ілля Іванов

14

Ще одне просте рішення за допомогою Regex. Вам слід скористатися цим

using System.Text.RegularExpressions;

і код є

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

12

Ви також можете спробувати це

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

приємно, але якщо у вихідному рядку у вас є пробіли між номерами, то це дасть вам 1 велику об'єднану рядок з об'єднаними обома номерами (немає місця)
Мохаммед Зекралла

11

Просто використовуйте RegEx, щоб відповідати рядок, а потім конвертувати:

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

9

Ось ще один Linqпідхід, який витягує перше число з рядка.

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

Приклади:

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

9

Для тих, хто хоче десяткове число з рядка з Regex у двох рядках:

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

Те саме стосується плавучих , довгих тощо.


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
Це найкраща відповідь, яка дала мені те, що я хотів, а це масив з декількох чисел у рядку. Якби тільки він міг ігнорувати коми в числах (тисяча роздільник), то це було б ідеально! :-)
Сагар

9

Це можна зробити за допомогою Stringвластивості, як показано нижче:

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

який дає лише число з рядка.



7

У запитанні прямо не вказано, що ви просто хочете, щоб символи були від 0 до 9, але не було б думкою, що це вірно з вашого прикладу та коментарів. Отже ось код, який це робить.

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

Чому ви не хочете використовувати Char.IsDigit () - Числа включають символи, такі як дроби, підписки, надписи, римські цифри, чисельники валют, обведені цифри та спеціальні цифри для сценарію.


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

Отримайте всі числа в рядку. Отже, якщо ви використовуєте для прикладу "1 плюс 2", він отримає "12".


5

Метод розширення для отримання всіх позитивних чисел, що містяться в рядку:

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

Якщо ви хочете негативні числа, просто змініть цей код, щоб обробити знак мінус (- )

Враховуючи цей вхід:

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

Отриманий список номерів буде:

[1989, 27, 2016]

5

якщо число має десяткову точку, ви можете використовувати нижче

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

результати:

"що-небудь 876,8 нічого" ==> 876,8

"що-небудь 876 що завгодно" ==> 876

"876435 $" ==> 876435

"876,435 $" ==> 876,435

Зразок: https://dotnetfiddle.net/IrtqVt


1
Дуже дякую за цю відповідь. Я використовую C # і VS2017 і намагався зрозуміти, як мені знайти значення. Дякую ще раз за вашу відповідь.
Бульбашки


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

Цей код використовується для пошуку всього цілого значення в рядку.
Маной Гупта

Було б краще додати якийсь опис безпосередньо у відповідь, ніж публікувати його окремо як коментар. Коментарі не завжди видно одразу.
Джон Дворак

2

Цікавий підхід міститься тут Ахмад Mageed, використовує Regex і StringBuilder для вилучення чисел в тому порядку , в якому вони з'являються в рядку.

Приклад використання Regex.Split на основі допису Ахмада Магіда такий:

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

Ось мій Алгоритм

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

ось моє рішення

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

На основі останнього зразка я створив метод:

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.