Как я могу получить последние четыре символа из строки в C #?

309

Предположим, у меня есть строка:

"34234234d124"

Я хочу получить последние четыре символа этой строки, которая есть "d124". Я могу использовать SubString, но для этого нужна пара строк кода, включая именование переменной.

Можно ли получить этот результат в одном выражении с помощью C #?

KentZhou
источник
3
Что вы хотите, когда есть менее 4 символов?
агент-ю
12
4 > mystring.length ? mystring : mystring.Substring(mystring.length -4);
Джодрелл
3
В Python решение простое: "hello world"[-4:]. Я надеюсь, что будущая версия C # сделает это так же просто.
полковник Паник
@ColonelPanic, теперь вы можете с C # 8.0: "hello world"[^4..]:-)
Фроде Эвенсен

Ответы:

407
mystring.Substring(Math.Max(0, mystring.Length - 4)); //how many lines is this?

Если вы уверены, что длина вашей строки не менее 4, то она еще короче:

mystring.Substring(mystring.Length - 4);
Армен Цирунян
источник
13
Кроме того, он потерпит неудачу, если mystringдлина менее 4 символов.
Джордж Дакетт
3
+1, потому что я думаю, что твое немного более читабельно, чем @ dtb
Джордж Дакетт
Взять пару строк кода (которые ОП уже знал) и поместить их в одну строку - это не то же самое, что одно выражение.
Бух Бух
1
Мне это нравится. Простой и элегантный, он принимает максимум, поэтому, если ваша строка меньше 0, вы не получите исключение вне индекса.
Бреттикус
+1 простой и в точку, охватывает все основы. Метод расширения, предложенный Stecya, также хорош, но немного перегружен, если вы делаете это только один раз.
Морваэль
205

Вы можете использовать метод расширения :

public static class StringExtension
{
    public static string GetLast(this string source, int tail_length)
    {
       if(tail_length >= source.Length)
          return source;
       return source.Substring(source.Length - tail_length);
    }
}

А затем позвоните:

string mystring = "34234234d124";
string res = mystring.GetLast(4);
Stecya
источник
11
Мне это нравится, но я бы, наверное, просто назвал это Last (). В конце концов Substring () не является GetSubstring ().
Бух Бух
21
Возможно, назовите его Tail (), так как Last конфликтует с расширением Linq Last ().
Крейг Кертис,
5
+1 за то, что он "намного длиннее 1 строки". Очень неприятно видеть нечитаемый код из-за экономии строк.
Фабио Мильейру,
2
Или назовите его Right () для согласованности с VisualBasic в соответствии с ответом @RJ Programmer (я не хочу добавлять другую сборку только для одной функции).
Христово
3
Я люблю это решение.
Люк
46

Все, что вам нужно сделать, это ..

String result = mystring.Substring(mystring.Length - 4);
звезда
источник
2
Нет, если вы хотите, чтобы было выброшено исключение, если длина меньше 4 ...
Милош Мрдович
45

Хорошо, я вижу, что это старый пост, но почему мы переписываем код, уже предоставленный в фреймворке?

Я бы предложил добавить ссылку на фреймворк DLL "Microsoft.VisualBasic"

using Microsoft.VisualBasic;
//...

string value = Strings.Right("34234234d124", 4);
RJ программист
источник
8
Хороший пример времени, чтобы использовать функциональность VB
Брайан Уайт
3
Я тебя люблю. Большую часть моего опыта в программировании я получил на VB, поэтому обнаружение, что я могу использовать все те функции, с которыми я так хорошо знаком, просто потрясающе
Бен Стромбек,
6
Я никогда не могу понять, если использование MS.VB хорошая идея - почему это шунтируется в VisualBasicпространство имен? TextFieldParserэто еще один пример. Почему эти утилиты так странно учтены?
ruffin
6
Я чувствую, что это должен быть принятый ответ. Зачем изобретать велосипед?
Зак
2
@Bomboca: Мы можем быть уверены, что это будет продолжаться, пока Microsoft продолжает поддерживать Visual Basic. Он включен в выпуск 4.6, и я не могу найти ничего явного или подразумеваемого от MS, что они планируют прекратить поддержку VB.Net в качестве языка разработки.
RJ Programmer
30
string mystring = "34234234d124";
mystring = mystring.Substring(mystring.Length-4)
Cem
источник
26

Использование Substring на самом деле довольно короткое и читаемое:

 var result = mystring.Substring(mystring.Length - Math.Min(4, mystring.Length));
 // result == "d124"
DTB
источник
17

Вот еще одна альтернатива, которая не должна работать слишком плохо (из-за отложенного выполнения ):

new string(mystring.Reverse().Take(4).Reverse().ToArray());

Хотя метод расширения для этой цели mystring.Last(4), безусловно, является самым чистым решением, хотя и немного больше работы.

Андре Луус
источник
1
@BrianWhite Люди капризны после нового года?
Конрад Вилтерстен
1
Хорошее решение. мне это нравится. Но вы забыли другой Реверс, чтобы получить правильную строку. Должно быть: новая строка (mystring.Reverse (). Take (4) .Reverse (). ToArray ());
Юрий Моралес
Ааа, да, вы правы - мой умственный компилятор не думал так далеко. К сожалению, это делает его еще хуже! :)
Андре Луус
1
Из-за ToArray нет отложенного выполнения
1
Я не думаю, что вы понимаете, @ BjörnAliGöransson, моя точка зрения заключалась в том, Reverse().Take(4).Reverse()что не каждый перечисляет всю строку, это происходит только при последнем ToArrayвызове. Если бы не было такой вещи, как отложенное выполнение, она бы перевела на Reverse().ToArray().Take(4).ToArray().Reverse().ToArray(). Это, конечно, предполагает, что эти расширения являются отложенным типом - который я не проверял. Конструкторы String не принимают IEnumerable, поэтому вам нужно перечислить его в массив в этой точке.
Андре Луус
17

Вы можете просто использовать Substringметод C #. Например

string str = "1110000";
string lastFourDigits = str.Substring((str.Length - 4), 4);

Он вернет результат 0000.

Амит Кумават
источник
7
На это ответили как 28 раз, и вы добавили это снова? И зачем использовать перегрузку с двумя параметрами вместо той, которая только получает startIndex?
Андрей
Именно тот ответ, который мне был нужен. Спасибо, что поделились @Amit Kumawat.
Дэрил
12

Простое решение будет:

string mystring = "34234234d124";
string last4 = mystring.Substring(mystring.Length - 4, 4);
Анис Дин
источник
7
mystring = mystring.Length > 4 ? mystring.Substring(mystring.Length - 4, 4) : mystring;
Майкл Бургграф
источник
Хорошо, но я думаю, что ты имел в виду =нет =+.
dotancohen
1
mystring.Substring (mystring.Length - 4, 4) - это то же самое, что и mystring.Substring (mystring.Length - 4)
Мо Ховард
6

Это просто так:

int count = 4;
string sub = mystring.Substring(mystring.Length - count, count);
Даниэль ДиПаоло
источник
6

По сравнению с некоторыми предыдущими ответами основное отличие состоит в том, что этот фрагмент кода учитывается, когда входная строка:

  1. Ноль
  2. Больше или соответствует запрошенной длине
  3. Короче, чем запрошенная длина.

Вот:

public static class StringExtensions
{
    public static string Right(this string str, int length)
    {
        return str.Substring(str.Length - length, length);
    }

    public static string MyLast(this string str, int length)
    {
        if (str == null)
            return null;
        else if (str.Length >= length)
            return str.Substring(str.Length - length, length);
        else
            return str;
    }
}
Марсело Финки
источник
4

Определение:

public static string GetLast(string source, int last)
{
     return last >= source.Length ? source : source.Substring(source.Length - last);
}

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

GetLast("string of", 2);

Результат:

из

Эрчин Дедеоглу
источник
3

Это не сработает для любой длины строки.

string mystring = "34234234d124";
string last4 = Regex.Match(mystring, "(?!.{5}).*").Value;
// last4 = "d124"
last4 = Regex.Match("d12", "(?!.{5}).*").Value;
// last4 = "d12"

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

Изменить: я думаю, что это регулярное выражение будет более эффективным:

@".{4}\Z"
Агент-J
источник
5
Определенно излишним. Я бы придерживался простых строковых методов для этого.
tsells
Второй вариант не возвращает трехбуквенную строку при вызове с трехбуквенным аргументом, поэтому он не эквивалентен вашей первой оригинальной версии, использующей отрицательный взгляд! :-)
avl_sweden
3

Используйте универсальный Last<T>. Это будет работать с ЛЮБОЙ IEnumerable, включая строку.

public static IEnumerable<T> Last<T>(this IEnumerable<T> enumerable, int nLastElements)
{
    int count = Math.Min(enumerable.Count(), nLastElements);
    for (int i = enumerable.Count() - count; i < enumerable.Count(); i++)
    {
        yield return enumerable.ElementAt(i);
    }
}

И конкретный для строки:

public static string Right(this string str, int nLastElements)
{
    return new string(str.Last(nLastElements).ToArray());
}
Адриано Карнейро
источник
1
Вот это да. Overkill. Может быть, что-то вроде enumerable.Skip (enumerable.Count () - nLastElements)?
Бух Бух
Я не согласен с @BuhBuh об этом излишнем. Но я предпочитаю «Последний» как «Право» как имя. Я немного брезглив по поводу перегрузки существующего Last of IEnumerable <T>. Я тоже склоняюсь к «Пропустить».
Правдоподобно отрицаемый
Мне нравится это решение. Не просто, но интересно при изучении IEnumerable.
pKarelian
1

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

    /// <summary>
    /// Returns characters slices from string between two indexes.
    /// 
    /// If start or end are negative, their indexes will be calculated counting 
    /// back from the end of the source string. 
    /// If the end param is less than the start param, the Slice will return a 
    /// substring in reverse order.
    /// 
    /// <param name="source">String the extension method will operate upon.</param>
    /// <param name="startIndex">Starting index, may be negative.</param>
    /// <param name="endIndex">Ending index, may be negative).</param>
    /// </summary>
    public static string Slice(this string source, int startIndex, int endIndex = int.MaxValue)
    {
        // If startIndex or endIndex exceeds the length of the string they will be set 
        // to zero if negative, or source.Length if positive.
        if (source.ExceedsLength(startIndex)) startIndex = startIndex < 0 ? 0 : source.Length;
        if (source.ExceedsLength(endIndex)) endIndex = endIndex < 0 ? 0 : source.Length;

        // Negative values count back from the end of the source string.
        if (startIndex < 0) startIndex = source.Length + startIndex;
        if (endIndex < 0) endIndex = source.Length + endIndex;         

        // Calculate length of characters to slice from string.
        int length = Math.Abs(endIndex - startIndex);
        // If the endIndex is less than the startIndex, return a reversed substring.
        if (endIndex < startIndex) return source.Substring(endIndex, length).Reverse();

        return source.Substring(startIndex, length);
    }

    /// <summary>
    /// Reverses character order in a string.
    /// </summary>
    /// <param name="source"></param>
    /// <returns>string</returns>
    public static string Reverse(this string source)
    {
        char[] charArray = source.ToCharArray();
        Array.Reverse(charArray);
        return new string(charArray);
    }

    /// <summary>
    /// Verifies that the index is within the range of the string source.
    /// </summary>
    /// <param name="source"></param>
    /// <param name="index"></param>
    /// <returns>bool</returns>
    public static bool ExceedsLength(this string source, int index)
    {
        return Math.Abs(index) > source.Length ? true : false;
    }

Так что если у вас есть строка типа «Это метод расширения», вот несколько примеров и результатов, которые можно ожидать.

var s = "This is an extension method";
// If you want to slice off end characters, just supply a negative startIndex value
// but no endIndex value (or an endIndex value >= to the source string length).
Console.WriteLine(s.Slice(-5));
// Returns "ethod".
Console.WriteLine(s.Slice(-5, 10));
// Results in a startIndex of 22 (counting 5 back from the end).
// Since that is greater than the endIndex of 10, the result is reversed.
// Returns "m noisnetxe"
Console.WriteLine(s.Slice(2, 15));
// Returns "is is an exte"

Надеюсь, эта версия будет полезна для кого-то. Он работает как обычно, если вы не используете отрицательные числа, и предоставляет значения по умолчанию для параметров вне диапазона.

ирландский
источник
1
string var = "12345678";

if (var.Length >= 4)
{
    var = var.substring(var.Length - 4, 4)
}

// result = "5678"
Eidan
источник
1

Предполагая, что вы хотите строки между строкой, которая находится в 10 символах от последнего символа, и вам нужно всего 3 символа.

Скажем StreamSelected = "rtsp://72.142.0.230:80/SMIL-CHAN-273/4CIF-273.stream"

В приведенном выше, мне нужно извлечь то, "273"что я буду использовать в запросе базы данных

        //find the length of the string            
        int streamLen=StreamSelected.Length;

        //now remove all characters except the last 10 characters
        string streamLessTen = StreamSelected.Remove(0,(streamLen - 10));   

        //extract the 3 characters using substring starting from index 0
        //show Result is a TextBox (txtStreamSubs) with 
        txtStreamSubs.Text = streamLessTen.Substring(0, 3);
Shinn_33
источник
Этот вопрос явно запрашивает последние четыре символа в строке. Вы, кажется, отвечаете на другой вопрос, связанный с извлечением вещей из середины строки. Также Substringуже позволяет передавать начальную точку и длину, поэтому не уверен, почему бы вам не использовать это вместо того, Removeчтобы сначала удалить начало.
Крис
0

Обновление 2020 : C # 8.0, наконец, делает это легко:

> "C# 8.0 finally makes this easy"[^4..]
"easy"

Вы также можете разрезать массивы таким же образом, см. Индексы и диапазоны .

Полковник паника
источник