Какой самый быстрый способ извлечь 5-значное число из строки в C#

какой самый быстрый способ извлечь 5-значное число из строки в C#.

у меня есть

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

Любые другие?

Зависит от формата строки! Что еще в нем? Могут ли цифры появляться где угодно .. ??

DilbertDave 04.11.2008 19:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
1
5 837
8
Перейти к ответу Данный вопрос помечен как решенный

Ответы 8

Вы имеете в виду преобразовать строку в число? Или найти первую пятизначную строку и затем превратить ее в число? В любом случае вы, вероятно, будете использовать десятичный. или int.Parse.

Я считаю, что регулярные выражения - неправильный подход. Более эффективный подход - просто пройтись по строке в поисках цифры, а затем продвинуть 4 символа и проверить, все ли они цифры. Если они есть, у вас есть подстрока. Он не такой прочный, нет, но и накладных расходов тоже нет.

Используйте регулярное выражение (\ d {5}), чтобы найти вхождение 5-значного числа в строке, и используйте int.Parse или decimal.Parse для совпадений.

В случае, когда в text есть только один номер.

int? value = null;
string pat = @"\d{5}"
Regex r = new Regex(pat);
Match m = r.Match(text);
if (m.Success)
{
   value = int.Parse(m.Value);
}

Как отмечает @Jon Skeet, если вы заранее знаете характер ввода, могут быть гораздо более быстрые способы сделать это. Это достаточно быстрый и надежный способ сделать это в условиях неизвестных входных форматов.

tvanfosson 04.11.2008 20:11

Ни в коем случае не используйте регулярные выражения. Он намного мощнее, чем вам нужно, и эта мощность, вероятно, снизит производительность.

Если вы можете дать более подробную информацию о том, что вам нужно, мы можем написать соответствующий код ... (Тестовые примеры были бы идеальными.)

да. Если вы знаете характер ввода, есть гораздо лучшие способы. Если, например, вы знаете, что на входе есть одно число, а других нет, то вы можете перебирать символы, пока не найдете цифру, а затем начать «накапливать» значение по следующим 4 цифрам.

tvanfosson 04.11.2008 20:08

Если числа существуют с другими символами, регулярные выражения - хорошее решение.

Пример: ([0-9] {5})

будет соответствовать - asdfkki12345afdkjsdl, 12345adfaksk или akdkfa12345

Если у вас есть простой тестовый пример, такой как «12345» или даже «12345abcd», вообще не используйте регулярное выражение. Их скорость не известна.

Для большинства строк метод грубой силы будет быстрее, чем RegEx.

Достаточно забавный пример:

string strIWantNumFrom = "qweqwe23qeeq3eqqew9qwer0q";

int num = int.Parse(
    string.Join( null, (
        from c in strIWantNumFrom.ToCharArray()
        where c == '1' || c == '2' || c == '3' || c == '4' || c == '5' ||
            c == '6' || c == '7' || c == '8' || c == '9' || c == '0'
        select c.ToString()
    ).ToArray() ) );

Несомненно, есть гораздо более быстрые способы и множество оптимизаций, которые зависят от точного формата вашей строки.

Ответ принят как подходящий

Подход с использованием регулярных выражений, вероятно, является самым быстрым для реализации, но не самым быстрым для выполнения. Я сравнил простое решение с регулярным выражением со следующим кодом ручного поиска и обнаружил, что код ручного поиска примерно в 2-2,5 раза быстрее для больших входных строк и до 4 раз быстрее для небольших строк:

static string Search(string expression)
{
  int run = 0;
  for (int i = 0; i < expression.Length; i++)
  {
    char c = expression[i];
    if (Char.IsDigit(c))
      run++;
    else if (run == 5)
      return expression.Substring(i - run, run);
    else
      run = 0;
  }
  return null;
}
const string pattern = @"\d{5}";
static string NotCached(string expression)
{
  return Regex.Match(expression, pattern, RegexOptions.Compiled).Value;
}

static Regex regex = new Regex(pattern, RegexOptions.Compiled);
static string Cached(string expression)
{
  return regex.Match(expression).Value;
}

Результаты для строки из 50 символов с 5-значной строкой посередине, более 10 ^ 6 итераций, задержка на вызов в микросекундах (меньшее число - быстрее):

Простой поиск: 0.648396us

Кэшированное регулярное выражение: 2.1414645us

Некешируемое регулярное выражение: 3.070116us

Результаты для строки размером ~ 40 КБ с 5-значной строкой посередине за 10 ^ 4 итераций, задержка на вызов в микросекундах (меньшее число - быстрее):

Простой поиск: 423.801us

Кэшированное регулярное выражение: 1155.3948us

Некешируемое регулярное выражение: 1220.625us

Немного удивительно: я ожидал, что Regex, который скомпилирован в IL, будет сопоставим с ручным поиском, по крайней мере, для очень больших строк.

Это могло быть быстрее ...

public static string DigitsOnly(string inVal)
        {
            char[] newPhon = new char[inVal.Length];
            int i = 0;
            foreach (char c in inVal)
                if (c.CompareTo('0') > 0 && c.CompareTo('9') < 0)
                    newPhon[i++] = c;
            return newPhon.ToString();
        }

если вы хотите ограничить его максимум пятью цифрами, тогда

public static string DigitsOnly(string inVal)
        {
            char[] newPhon = new char[inVal.Length];
            int i = 0;
            foreach (char c in inVal)
                if (c.CompareTo('0') > 0 && c.CompareTo('9') < 0 && i < 5)
                    newPhon[i++] = c;
            return newPhon.ToString();
        }

Другие вопросы по теме