Получить строку после String.indexof в С#

В настоящее время я разрабатываю приложение на С#, где мне нужно получить подстроку после определенного символа внутри строки.

else if (txtPriceLimit.Text.Contains('.') && char.IsNumber(e.KeyChar))
{
    int index = txtPriceLimit.Text.IndexOf('.');
    string pennies = txtPriceLimit.Text.Substring(index, txtPriceLimit.Text.Length);
    Console.WriteLine("Pennies: " + pennies);
}

По какой-то причине он продолжает придумывать IndexOutOfRangeException. Как я могу получить содержимое строки из индекса до конца?

Спасибо за любую помощь, которую вы можете предоставить.

EDIT: Просто обнаружил, что различные вещи, которые я пробовал, которые были предложены, действительно работают, за исключением того, что он не получает значение от последней кнопки, нажатой в текстовое поле. Для этого я использую событие KeyPress.

Например, если я вхожу .123, он будет печатать только 12. Затем, если я добавлю 4 в конец, он будет печатать 123

Ответы

Ответ 1

перегрузка String.Substring, который вы используете, принимает начальный индекс и указанную длину. В качестве начального индекса вы используете расположение ".", но в качестве длины вы используете длину всей строки. Если index больше 0, это вызовет исключение (как вы видели).

Вместо этого просто используйте это:

string pennies = txtPriceLimit.Text.Substring(index + 1);

Это приведет к тому, что все символы в txtPriceLimit.Text после будут находиться в < <21 > . Обратите внимание, что нам нужно добавить 1 к индексу; иначе "." будет включено в результирующую подстроку.

Ответ 2

Просто попробуйте сделать это вместо

string pennies = txtPriceLimit.Text.Split('.')(1);

Это предполагает, что в строке есть только 1 . и что в строке будет 1.

Ответ 3

Используйте это, это определенно будет работать: -

else if (txtPriceLimit.Text.Contains('.') && char.IsNumber(e.KeyChar))
{
    int index = txtPriceLimit.Text.IndexOf('.');
    string pennies = txtPriceLimit.Text.Substring(index+1, txtPriceLimit.Text.Length-(index+1));
    pennies=pennies+e.KeyChar.ToString();
    Console.WriteLine("Pennies: " + pennies);
}

Ответ 4

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

Это метод расширения, который я написал, который вернет текст в этой строке txt, следуя параметру строковое значение:

Листинг 1:

public static string TextFollowing(this string txt, string value) {
  if (!String.IsNullOrEmpty(txt) && !String.IsNullOrEmpty(value)) {
    int index = txt.IndexOf(value);
    if (-1 < index) {
      int start = index + value.Length;
      if (start <= txt.Length) {
        return txt.Substring(start);
      }
    }
  }
  return null;
}

Пример 1:

string exampleText = "My cat is bad.";
string afterCat = exampleText.TextFollowing("cat");
// afterCat = " is bad.";

Для людей, которые не перешли к методам расширения, вы можете получить те же результаты из инструмента, аналогично описанного следующим образом:

Листинг 2:

public static string TextFollowing(string searchTxt, string value) {
  if (!String.IsNullOrEmpty(searchTxt) && !String.IsNullOrEmpty(value)) {
    int index = searchTxt.IndexOf(value);
    if (-1 < index) {
      int start = index + value.Length;
      if (start <= searchTxt.Length) {
        return searchTxt.Substring(start);
      }
    }
  }
  return null;
}

Пример 2:

string exampleText = "My cat is bad.";
string afterCat = TextFollowing(exampleText, "cat");
// afterCat = " is bad.";

В каждом из приведенных выше примеров, если exampleText был пустой строкой, значение поиска было null или Empty String, или если значение поиска не найдено, результирующая строка будет null.

У меня есть этот код в моем списке инструментов, где он используется в бесчисленных местах в многочисленных проектах, и он всегда отлично работает.

Ответ 5

Ответ пончика правильный.

Поскольку второй параметр подстроки длина не "конечный индекс", его ответ является гораздо более чистым эквивалентом:

string pennies = txtPriceLimit.Text.Substring(index, index-txtPriceLimit.Text.Length);

Ответ 6

версия VisualBasic

Код, чтобы найти подстроку, если она найдена, возвращает конечную часть - оставшуюся часть строки сразу же (конец конца) найденной подстроки.

jp2code отвечал моей цели элегантным способом. В дополнение к примерам, автор также указал, что код был хорошо опробован и протестирован с течением времени. VisualBasic эквивалент его/ее кода:

Imports System.Runtime.CompilerServices

Module StringExtensions
    <Extension()>
    Public Function TextFollowing(txt As String, value As String) As String
        If Not String.IsNullOrEmpty(txt) AndAlso Not String.IsNullOrEmpty(value) Then
            Dim index As Integer = txt.IndexOf(value)
            If -1 < index Then
                Dim start As Integer = index + value.Length
                If start <= txt.Length Then
                    Return txt.Substring(start)
                End If
            End If
        End If
        Return Nothing
    End Function
End Module

Код был протестирован с использованием VS Community 2017.

Пример использования

Dim exampleText As String = "C-sharp to VisualBasic"
Dim afterCSharp = exampleText.TextFollowing("to")
'afterCSharp = " VisualBasic"

Метод расширения TextFollowing() теперь доступен для объектов String.

  • Строка 1: exampleText - String, и поэтому доступен наш метод расширения
  • Строка 2: exampleText.TextFollowing() использует метод расширения

Дополнительный метод

Может быть полезно иметь дополнительный метод - получить предыдущую часть строки. Дополнительные методы расширения записываются и помещаются вместе в один комбинированный модуль кода:

Imports System.Runtime.CompilerServices

Module StringExtensions
    <Extension()>
    Public Function TextFollowing(txt As String, value As String) As String
        If Not String.IsNullOrEmpty(txt) AndAlso Not String.IsNullOrEmpty(value) Then
            Dim index As Integer = txt.IndexOf(value)
            If -1 < index Then
                Dim start As Integer = index + value.Length
                If start <= txt.Length Then
                    Return txt.Substring(start)
                End If
            End If
        End If
        Return Nothing
    End Function
    <Extension()>
    Public Function TextPreceding(txt As String, value As String) As String
        If Not String.IsNullOrEmpty(txt) AndAlso Not String.IsNullOrEmpty(value) Then
            Dim index As Integer = txt.IndexOf(value)
            If -1 < index Then
                Return txt.Substring(0, index)
            End If
        End If
        Return Nothing
    End Function
End Module

Пример использования

Dim exampleText As String = "C-sharp to VisualBasic"
Dim beforeVisualBasic = exampleText.TextPreceding("to")
'beforeVisualBasic = "C-sharp "

В моем случае использования необходимо проверить, есть ли LargeString.Contains(SmallString) до использования этих методов расширения. Для более быстрого выполнения кода это могло быть объединено с описанными выше методами расширения, которых я не использовал. Это связано с тем, что никакая медленность не возникает, поэтому предпочтение отдается повторному использованию кода.