从字符串中提取最右边的n个字符

125

如何从一个字符串中提取由另一个字符串的最右边6个字符组成的子字符串?

例如:我的字符串是"PER 343573"。现在我想提取"343573"

我该如何做到这一点呢?


你可以使用VB.NET Right方法的源代码。但需要先转换为C#:http://referencesource.microsoft.com/#Microsoft.VisualBasic/Strings.vb#0dbb15fffce19341 使用http://converter.telerik.com/进行转换。 - Darren Griffith
但是 VB 代码依赖于 C# 字符串中的 Substring 函数。 - Our Man in Bananas
这并不是一个非常好的方法,但如果你赶时间,你可以添加对Microsoft.VisualBasic.dll的引用,然后使用Right方法。它不是一个扩展方法。你必须像这样使用它: string endOfString = Strings.Right(wholeString, 6); - Alan McBee
3
可能是如何在C#中获取字符串的最后4个字符?的重复问题。 - drzaus
22个回答

176
string SubString = MyString.Substring(MyString.Length-6);

39
如果字符串长度不足以满足所需字符的数量,这种方法就无法正确运行。 - stevehipwell
1
根据OP的具体需求,我们也可以使用正则表达式来解决。如果他/她只想要字符串末尾的数字,那么这绝对是最简单的解决方案,特别是当数字位数可能在以后的软件升级中发生变化时。 - Joey
2
@Johannes Rössel - 我是正则表达式的忠实粉丝(请看我的回答),但我从不建议在这种简单情况下使用它们。任何使用函数包装器的答案都比正则表达式更适合代码维护。扩展方法(或标准函数,如果是.NET 2.0)是最佳解决方案。 - stevehipwell
@Stevo3000 - 拥有一个在字符串长度错误时抛出异常的解决方案是一个有效的解决方案。虽然不是唯一的解决方案,但仍然有效。 - Marc L.
3
为了严谨起见,仅标题提到了“n个字母”。实际问题所询问的是“最右边的六个字母”:) - Chris Rogers
显示剩余2条评论

73
编写一个扩展方法表达Right(n);函数。该函数应处理空或空字符串并返回空字符串,对于长度小于最大长度的字符串应返回原始字符串,对于长度长于最大长度的字符串应返回右侧字符的最大长度。
public static string Right(this string sValue, int iMaxLength)
{
  //Check if the value is valid
  if (string.IsNullOrEmpty(sValue))
  {
    //Set valid empty string as string could be null
    sValue = string.Empty;
  }
  else if (sValue.Length > iMaxLength)
  {
    //Make the string no longer than the max length
    sValue = sValue.Substring(sValue.Length - iMaxLength, iMaxLength);
  }

  //Return the string
  return sValue;
}

起始索引不能小于0。 - James
2
@James - 在调用子字符串之前,它不会像sValue.Length > iMaxLength那样! - stevehipwell
5
很棒的回答,但在C#代码中看到匈牙利命名法有点让人吃惊。 - Jerad Rose
1
@JeradRose - 我在一个项目中工作,代码库从VB3应用程序演变而来(大部分是VB.NET),因此还有一些残留物。 - stevehipwell
@Stevo3000 啊,那么就有道理了。 :) - Jerad Rose
4
@Jalle,VB.NET具有Left、Right和Mid等顶级函数,以及许多其他有用的东西,这些都不是C#的一部分。不确定原因,因为其中许多函数都很不错。 - ingredient_15939

43

使用扩展方法可能更好:

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

用法

string myStr = "PER 343573";
string subStr = myStr.Right(6);

20
如果你试图对空字符串使用任何方法,它将会抛出 NullReferenceException 异常,就像对 null 对象调用方法一样。请注意,这里的空字符串指的是未初始化或者为 null 的字符串变量。 - James
1
str.Length - length 可能为负数。第二个参数是可选的,不需要传递长度。 - iheartcsharp
1
@JMS10,这确实可能是问题,但更多的是调用者的问题,而不是我的问题。另外,是的,你说得对,你可以在这里使用只接受单个参数的覆盖方法。 - James
str?.Substring(str.Length - length, length); str?.Substring(str.Length - length, length); - Ludwo

27
using System;

public static class DataTypeExtensions
{
    #region Methods

    public static string Left(this string str, int length)
    {
        str = (str ?? string.Empty);
        return str.Substring(0, Math.Min(length, str.Length));
    }

    public static string Right(this string str, int length)
    {
        str = (str ?? string.Empty);
        return (str.Length >= length)
            ? str.Substring(str.Length - length, length)
            : str;
    }

    #endregion
}

不应该错误,返回空字符串而非null,返回经过修剪的或基础值。使用像 "testx".Left(4) 或 str.Right(12) 这样的方式。


16

MSDN

String mystr = "PER 343573";
String number = mystr.Substring(mystr.Length-6);

编辑:太慢了...


11
如果您不确定字符串的长度,但确定单词数(在此情况下始终为2个单词,例如“xxx yyyyyy”),最好使用split函数。
string Result = "PER 343573".Split(" ")[1];

这将始终返回您字符串的第二个单词。


1
好的,让我们假设 OP 的文本总是有空格的,就像他的示例一样 :) - Christian
1
嗨,Christian :) 我们都知道一个答案不止几行。我只是简要回答了问题,当然,在实际代码中还有很多需要考虑的事情。 - Mahdi Tahsildari

9

这不完全是您所要求的,但仅查看示例,似乎您正在寻找字符串的数字部分。

如果始终如此,那么使用正则表达式是一个好方法。

var regex= new Regex("\n+");
string numberString = regex.Match(page).Value;

-1 正则表达式对于这种情况有点过头了,特别是已经有内置方法可以完成它。 - James
1
我并不是在争论如果你只需要最后6位就使用这种方法,但如果你的目标是提取一个数字(比如ID),它可能在未来变成5或7位数,那么这是一种更好的方式。 - chills42
2
虽然这个回答有点老,但我支持使用正则表达式。特别是因为在.NET的String实现中仍然没有内置方法可以做到这一点。否则,这个问题可能不会存在。 - CrazyIvan1974
@CrazyIvan1974 不确定你在评论中为什么提到了我。 - James

9

由于您正在使用 .NET,该编译为 MSIL,只需引用 Microsoft.VisualBasic,并使用 Microsoft 内置的 Strings.Right 方法

using Microsoft.VisualBasic;
...
string input = "PER 343573";
string output = Strings.Right(input, 6);

不需要创建自定义扩展方法或其他工作。只需引用一行简单的代码即可实现结果。
此外,关于使用Visual Basic方法与C#一起使用的更多信息已在其他地方记录下来。我个人第一次尝试解析文件时偶然发现了它,并且发现使用Microsoft.VisualBasic.FileIO.TextFieldParser类对于解析.csv文件非常有用,这一点在这个SO线程中有所体现。

1
这种方法在另一个SO线程中也有详细介绍:https://dev59.com/i2w15IYBdhLWcg3wxuch#15255454 - Aaron Thomas
1
这太疯狂了!但作为VB程序员,能够一次性地掌控C#程序员感觉不错! - SteveCinq

6
请使用以下内容:
String text = "PER 343573";
String numbers = text;
if (text.Length > 6)
{
    numbers = text.Substring(text.Length - 6);
}

返回文本后6个字符:text?.Substring(text.Length - 6) - Ludwo

5
var str = "PER 343573";
var right6 = string.IsNullOrWhiteSpace(str) ? string.Empty 
             : str.Length < 6 ? str 
             : str.Substring(str.Length - 6); // "343573"
// alternative
var alt_right6 = new string(str.Reverse().Take(6).Reverse().ToArray()); // "343573"

这个函数支持在str中输入任意字符。而另一段代码不支持空字符串null,第一个函数更快,但第二个更加紧凑。

如果知道str中包含短字符串,则我更喜欢第二种方法。但如果是长字符串,则第一个方法更合适。

例如:

var str = "";
var right6 = string.IsNullOrWhiteSpace(str) ? string.Empty 
             : str.Length < 6 ? str 
             : str.Substring(str.Length - 6); // ""
// alternative
var alt_right6 = new string(str.Reverse().Take(6).Reverse().ToArray()); // ""

或者

var str = "123";
var right6 = string.IsNullOrWhiteSpace(str) ? string.Empty 
             : str.Length < 6 ? str 
             : str.Substring(str.Length - 6); // "123"
// alternative
var alt_right6 = new string(str.Reverse().Take(6).Reverse().ToArray()); // "123"

1
我喜欢那个替代方案。冗长,但易于理解,并自动处理字符串过短的问题。 - Andrew Grothe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接