Найти и извлечь число из строки

320

У меня есть требование найти и извлечь число, содержащееся в строке.

Например, из этих строк:

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
Почему здесь нет ответа?
Виктор Стрибьев

Ответы:

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
@ Томас: Этот код не работает, он приводит к b == "System.Linq.Enumerable..". Правильнее (и даже проще) было быb = String.Join("", a.Where(char.IsDigit))
BlueRaja - Дэнни Пфлюгофт
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: О чем ты говоришь? В первоначальном вопросе был задан способ извлечь одно число из строки как в заголовке, так и в теле вопроса. Последующие изменения в вопросе (через год после моего ответа и позже) людьми, отличными от первоначального автора, изменили название на «цифры». Во всяком случае, это неправильное редактирование должно быть отменено.
Тим Питцкер,
181

Вот как я очищаю телефонные номера, чтобы получить только цифры:

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
ejcortes
источник
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

Tabares
источник
16

Вот Linqверсия:

string s = "123iuow45ss";
var getNumbers = (from t in s
                  where char.IsDigit(t)
                  select t).ToArray();
Console.WriteLine(new string(getNumbers));
spajce
источник
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]"));
BvdVen
источник
хорошо, но если у вас есть пробелы между числами в исходной строке, то это даст вам 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
Fubo
источник
9

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

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

То же самое относится и к float , long и т. Д.

Ричард Фу
источник
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
var match=Regex.Match(@"a99b",@"\d+");
if(match.Success)
{
    int val;
    if(int.TryParse(match.Value,out val))
    {
        //val is set
    }
}
расточитель
источник
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 () - числа включают такие символы, как дроби, нижние индексы, верхние индексы, римские цифры, числительные, окруженные числа и специфичные для скрипта цифры.

Atters
источник
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

Интересный подход предоставлен здесь Ахмадом Магидом, использующим 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);
Simba
источник
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;
    }
HS_Kernel
источник
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

Вы должны будете использовать Regex в качестве \d+

\d соответствует цифрам в данной строке.

Сачин Шанбхаг
источник
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"));
Watcharachai Unvijit
источник
0

Используя ответ @ tim-pietzcker сверху , будет работать следующее PowerShell.

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