Как мне правильно извлечь число, которое начинается и заканчивается одним и тем же номером

#c# #.net #algorithm

#c# #.net #алгоритм

Вопрос:

Я пытаюсь узнать, как извлечь все числа из строки, где число начинается со случайной цифры, которая находится в диапазоне от 0 до 9, а затем заканчивается той же самой, но если перед появлением следующей буквы есть еще одна такая цифра, она должна включать и эту.

Позвольте мне показать вам пример. Возьмем, к примеру, эту строку, 12346171par827here727next8number5052car затем моя программа извлекла бы 12346171 , 727 , 505

И что у меня есть до сих пор, это то, что, очевидно, не делает того, что должно, но я не могу найти хороший алгоритм.

Как мне правильно извлечь числа?

 string input = "12346171par827here727next8number5052car";

var charArray = input.ToArray();
int pos = 0;

var firstNum = 0;
var secondNum = 0;

for (int i = 0; i < charArray.Length; i  )
{
    if (char.IsDigit(charArray[i]))
    {
        firstNum = charArray[i];

        for (int j = i; j < charArray.Length; j  )
        {
            if (char.IsDigit(charArray[j]) amp;amp; charArray[j] == firstNum)
            {
                secondNum = charArray[j];
            }
        }

    }
}
  

Комментарии:

1. Я не уверен, что понимаю вывод здесь, почему результат не включает 123461 и 171 . Это ошибка, или это реальное поведение, которое вы хотите?

Ответ №1:

Простым способом добиться этого было бы использовать регулярные выражения. Вы можете использовать следующий шаблон регулярных выражений:

 ([0-9])[0-9]*1
  

ДЕМОНСТРАЦИЯ.

Подробные сведения:

 ([0-9])    # Matches a single digit and put it in group #1.
[0-9]*     # Matches zero or more digits.
1         # Matches the same string that was captured in group #1.
  

Вот полный пример:

 string input = "12346171par827here727next8number5052car";

string pattern = @"([0-9])[0-9]*1";
var matches = Regex.Matches(input, pattern);
foreach (Match match in matches)
{
    Console.WriteLine(match.Value);
}
  

Вывод:

 12346171
727
505
  

Обратите внимание, что приведенный выше шаблон будет соответствовать «505» из «6505». Если вы хотите предотвратить это, убедившись, что повторяющаяся цифра находится в начале числа, вы можете использовать отрицательный взгляд назад. В этом случае шаблон будет:

 (?<![0-9])([0-9])[0-9]*1
  

<a rel="noreferrer noopener nofollow" href="https:///regexstorm.net/tester?p=(?ДЕМОНСТРАЦИЯ.

Ответ №2:

Предполагая, что ваши правила правильно определены. Вы могли бы сделать это O (n) довольно эффективно с помощью старого доброго цикла for

Учитывая

 public static IEnumerable<string> Get(string input)
{
    int last = -1, first = -1;
    for (var index = 0; index < input.Length; index  )
        if (!char.IsDigit(input[index]))
        {
            if (last > 1)
                yield return input.Substring(first, last - first   1);
            first = last = -1;
        }
        else if (first == -1)
            first = index;
        else if (input[first] == input[index])
            last = index;
    if (last > 1)
        yield return input.Substring(first, last - first   1);
}
  

Использование

 var input = "12346171par827here727next8number5052car";
Console.WriteLine(string.Join(", ", Get(input)));
  

Вывод

 12346171, 727, 505
  

Полная демонстрация здесь