假设我有一个字符串:

"34234234d124"


我想获取此字符串的后四个字符"d124"。我可以使用SubString,但是它需要几行代码,包括命名变量。

是否可以使用C#在一个表达式中获得此结果?

评论

少于四个字符时您想要什么?

4> mystring.length吗? mystring:mystring.Substring(mystring.length -4);

在Python中,解决方案很简单:“ hello world” [-4:]。我希望将来的C#版本能够使它变得简单。

@ColonelPanic,现在您可以使用C#8.0:“ hello world” [^ 4 ..] :-)

@FrodeEvensen您在此处演示的函数的名称是什么,以便我可以详细了解它?

#1 楼

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


如果您肯定字符串的长度至少为4,则它的长度甚至更短:

mystring.Substring(mystring.Length - 4);


评论


另外,如果mystring少于4个字符,它将失败。

–乔治·达基特(George Duckett)
2011年6月20日15:25

+1是因为我认为您的可读性比@dtb的可读性高

–乔治·达基特(George Duckett)
2011年6月20日15:29

采取几行代码(OP已经知道)并将其挤在一行上与一个表达式实际上不是一回事。

– Buh Buh
2011年6月20日15:39



我喜欢。简单优雅,并采用最大值,因此如果您的字符串小于0,则不会出现索引不足异常。

–布雷蒂克斯
2013年3月13日在16:39



这种方法在空输入时失败

–iamdave
20年7月17日在15:58

#2 楼

您可以使用扩展方法:

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);


评论


我喜欢这个,但我可能会称其为Last()。毕竟Substring()不是GetSubstring()。

– Buh Buh
2011年6月20日15:44

也许在Last与Linq Extension Last()发生冲突时将其称为Tail()。

–克雷格·柯蒂斯(Craig Curtis)
2014年1月22日,1:17

+1使它“比1行长很多”。由于节省了行代码,所以看到不可读的代码真是令人讨厌。

–法比奥·米尔海罗(Fabio Milheiro)
2015年12月4日,11:43



或根据@RJ程序员的回答将其命名为Right()以与VisualBasic保持一致(我不想仅为一个函数添加另一个程序集)。

–christutty
16年1月9日在6:24

我喜欢这个解决方案。

–卢克
18年7月1日在15:19

#3 楼

您所要做的就是..

String result = mystring.Substring(mystring.Length - 4);


评论


如果长度小于4,则不希望引发异常。

–米洛斯·姆多维奇
19年3月21日在16:49

#4 楼

好的,所以我看到这是一篇老文章,但是为什么我们要重写框架中已经提供的代码?

我建议您添加对框架DLL“ Microsoft.VisualBasic”的引用

using Microsoft.VisualBasic;
//...

string value = Strings.Right("34234234d124", 4);


评论


一次使用VB功能的好例子

–布莱恩·怀特(Brian White)
13年3月18日在16:25

我爱你。我大部分的编程经验是VB,因此发现我可以使用我所熟悉的所有功能真是太棒了

– Ben Strombeck
2013年9月1日,下午1:39

我永远无法弄清楚使用MS.VB是否是个好主意-为什么将它分流到VisualBasic命名空间中? TextFieldParser是另一个示例。为什么这些实用程序是如此奇怪?

–松饼
2014年5月12日在18:26

我觉得这应该是公认的答案。为什么要重新发明轮子?

–扎克
14年8月4日在16:54

@Bomboca:我们可以放心,只要Microsoft继续支持Visual Basic,它将继续下去。它包含在4.6版本中,我无法从MS中找到任何明确或隐含的东西,他们计划停止支持VB.Net作为开发语言。

– RJ程序员
2015年12月14日在21:11



#5 楼

string mystring = "34234234d124";
mystring = mystring.Substring(mystring.Length-4)


#6 楼

实际上,使用Substring非常简短且易于阅读:

 var result = mystring.Substring(mystring.Length - Math.Min(4, mystring.Length));
 // result == "d124"


#7 楼

2020年更新:C#8.0最终使此操作变得容易:

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


您也可以用相同的方式对数组进行切片,请参见索引和范围。

评论


最好的方法=)

– PassionateDeveloper
20年8月12日在12:42

遗憾的是,它仅适用于.Net Core或/和Standard。这很漂亮。

–哈桑·古尔扎(Hassan Gulzar)
20年8月31日在8:49

#8 楼

这是另一个应该不会表现太差的选择(由于推迟执行):

还有更多工作。

评论


@BrianWhite人们新年过后会胡思乱想吗?

– Konrad Viltersten
13年3月27日在20:48

不错的解决方案。我喜欢。但是您忘记了其他Reverse来获取正确的字符串。必须为:new string(mystring.Reverse()。Take(4).Reverse()。ToArray());

–尤里·莫拉莱斯(Yuri Morales)
13年4月30日在18:45



嗯,是的,您是正确的-我的思维编译器认为没有那么远。可悲的是,这使它看起来更糟! :)

– Andre Luus
13年5月2日在6:59

由于ToArray不会延迟执行

–user3638471
16年7月9日在13:39

我想你不明白,@BjörnAliGöransson,我的意思是Reverse()。Take(4).Reverse()并不枚举整个字符串,它仅在最后的ToArray调用中发生。如果没有延迟执行之类的东西,它将转换为Reverse()。ToArray()。Take(4).ToArray()。Reverse()。ToArray()。当然,这假定这些扩展名是延迟类型-我没有检查。 String构造函数不接受IEnumerable,因此此时必须将其枚举为数组。

– Andre Luus
16年7月19日在8:19



#9 楼

您可以简单地使用C#的Substring方法。例如。

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


它将返回结果0000。

评论


这个答案已经回答了28次,您又添加了一次?以及为什么使用2参数超载而不是仅接收startIndex的参数?

–安德鲁(Andrew)
17年4月26日在17:45

正是我需要的答案。感谢分享@Amit Kumawat。

–达里尔
19年3月11日在9:36

#10 楼

一个简单的解决方案是:

string mystring = "34234234d124";
string last4 = mystring.Substring(mystring.Length - 4, 4);


#11 楼

定义:

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


用法:

GetLast("string of", 2);


结果:



#12 楼

mystring = mystring.Length > 4 ? mystring.Substring(mystring.Length - 4, 4) : mystring;


评论


很好,但是我认为您的意思是=不是= +。

– dotancohen
2012年7月17日在4:23

mystring.Substring(mystring.Length-4,4)与以下内容相同:mystring.Substring(mystring.Length-4)

–莫·霍华德
2015年5月1日21:58



#13 楼

与以前的答案相比,主要区别在于,当输入字符串为:


Null
大于或匹配请求的长度
/>比要求的长度短。

这里是:

 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;
    }
}
 


#14 楼

就是这样:

int count = 4;
string sub = mystring.Substring(mystring.Length - count, count);


#15 楼

这对于任何长度的字符串都不会失败。

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


这对于手头的任务来说可能是多余的,但是如果需要其他验证,则可能添加到正则表达式中。

编辑:我认为此正则表达式会更有效:

@".{4}\Z"


评论


绝对过分杀伤力。我会坚持使用简单的字符串方法。

–销售
2014年1月16日14:49

第二个变体在使用三字母参数调用时不会返回三字母字符串,因此它不等同于使用负前瞻的第一个精巧版本! :-)

–avl_sweden
2014年12月29日14:19



#16 楼

使用通用的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);
    }
}


以及特定于字符串的字符串:

评论


哇。过度杀伤力。也许像enumerable.Skip(enumerable.Count()-nLastElements)之类的东西?

– Buh Buh
2011年6月20日16:03

我不同意@BuhBuh的说法。但是我更喜欢“ Last”而不是“ Right”作为名称。我对于重载现有的IEnumerable 的Last感到有些沮丧。我也倾向于“跳过”。

–可否认
13年2月26日在22:27

我喜欢这个解决方案。学习IEnumerable并不简单,但很有趣。

– pKarelian
16-2-23在3:38

#17 楼

我整理了一些从各种来源修改而来的代码,这些代码将获得您想要的结果,并做更多的事情。我允许使用负的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"


希望此版本对某人有用。如果您不使用任何负数,它的运行方式与正常情况一样,并为超出范围的参数提供默认值。

#18 楼

string var = "12345678";

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

// result = "5678"


#19 楼

假设您想要的字符串位于距离最后一个字符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);


评论


该问题明确要求字符串中的最后四个字符。您似乎正在回答一个与从字符串中间提取内容有关的不同问题。另外,Substring已经允许您传递起点和长度,因此不确定为什么不使用它而不是使用Remove首先删除起点。

–克里斯
16-10-4在13:33

#20 楼

建议使用TakeLast方法,例如:new String(text.TakeLast(4).ToArray())

#21 楼

string var = "12345678";

var = var[^4..];

// var = "5678"


评论


请不要仅将代码发布为答案,还请提供解释代码的作用以及如何解决问题的方法。带有解释的答案通常会更有帮助,而且质量更好,并且更有可能引起反对。

– Tyler2P
20/12/28在13:14

#22 楼

我想使用C#8或更高版本中的新范围来扩展现有答案的提及:使代码可用于所有可能的字符串。如果您想复制代码,我建议使用示例5或6。
q412078q
1:切片结束部分-通过指定从头开始省略多少个字符-这就是VS 2019的建议:
string mystring ="C# 8.0 finally makes slicing possible";

2:分割结尾部分-通过指定从末尾开始的字符数:
string example1 = mystring[Math.Max(0, mystring.Length - 4)..] ;

3:分割结尾部分-通过替换最大/最小值使用?:运算符:
string example2 = mystring[^Math.Min(mystring.Length, 4)..] ;

我个人更喜欢第二和第三个变体,而不是第一个。
索引和范围的MS文档参考:
是否为空?但是,关于普遍性我们还没有完成。到目前为止,每个示例都将为null字符串引发异常。要考虑null(如果您在C#8或更高版本中不使用不可为null的字符串),并且不使用“ if”(经典示例“ with if”已在另一个答案中给出)来做到这一点,我们需要:
4 :切片考虑空值-通过指定要忽略的字符数:
string example3 = (mystring.length > 4)? mystring[^4..] : mystring); 

5:切片考虑空值-通过指定要采取的字符数:
string example4 = mystring?[Math.Max(0, mystring.Length - 4)..] ?? string.Empty;

6:切片考虑空值与?:运算符(以及另外两个'?'运算符;-)结合使用:
(不能将其整体放在字符串内插中,例如对于WriteLine。)
string example5 = mystring?[^Math.Min(mystring.Length, 4)..] ?? string.Empty;

7:等效对于C#6或7.x具有良好的旧Substring()的变体:
(不能将其整体放在字符串内插中,例如对于WriteLine。)
string example6 = (mystring?.Length > 4) ? filePath[^4..] : mystring ?? string.Empty;

优雅的降级效果?
/>我喜欢C#的新功能。像上一个示例一样,将它们放在一行上可能看起来有些多余。我们结束了一点点Perl´ish,不是吗?
但这是一个很好的学习示例,我可以在经过测试的库方法中使用它一次。
更好的是,我们可以摆脱它如果需要,请避免在现代C#中使用null进行处理。
这种作为快捷方式的库/扩展方法非常有用。尽管C#取得了进步,但您仍然必须编写自己的应用程序才能使它比重复上面的代码更容易使用,以满足每一个小的字符串操作需求。
我是使用BASIC的人之一,40年前已经对$(,)。有趣的是,也可以在C#中仍然使用VB的VB中的Strings.Right(,)。如另一个答案所示。
C#选择了精度而不是性能下降(与旧的BASIC相反)。
因此,请在这些答案中复制您喜欢的任何合适的变体,并为自己定义一个优美的快捷方式函数,我的是一个名为RightChars(int)的扩展函数。