如何最好地通过字符的最后一个出现位置来分割字符串?

87

假设我需要像这样分割字符串:

输入字符串:"My. name. is Bond._James Bond!" 输出2个字符串:

  1. "My. name. is Bond"
  2. "_James Bond!"

我尝试了以下方法:

int lastDotIndex = inputString.LastIndexOf(".", System.StringComparison.Ordinal);
string firstPart = inputString.Remove(lastDotIndex);
string secondPart= inputString.Substring(lastDotIndex + 1, inputString.Length - firstPart.Length - 1);

有没有更优雅的提出方式?


我会说下划线正是为了让你进行拆分而存在。在该符号上进行拆分,如果你真的需要输出的第二部分,可以手动添加它。 - Jeroen Vannevel
1
不清楚您想如何处理下划线。它是否总是存在?输出时应该删除吗?还是需要保留它? - Steve
5个回答

183

更新的答案(适用于C# 8及以上版本)

C# 8引入了一种名为范围和索引的新功能,它提供了一种更简洁的语法来处理字符串。

string s = "My. name. is Bond._James Bond!";
int idx = s.LastIndexOf('.');

if (idx != -1)
{
    Console.WriteLine(s[..idx]); // "My. name. is Bond"
    Console.WriteLine(s[(idx + 1)..]); // "_James Bond!"
}

原始答案(适用于C# 7及以下版本)

这是使用string.Substring(int, int)方法的原始答案。如果您喜欢,仍然可以使用此方法。

string s = "My. name. is Bond._James Bond!";
int idx = s.LastIndexOf('.');

if (idx != -1)
{
    Console.WriteLine(s.Substring(0, idx)); // "My. name. is Bond"
    Console.WriteLine(s.Substring(idx + 1)); // "_James Bond!"
}

2
奖金 - 如果 idx == -1,即没有 '.',则不会出现问题 - CAD bloke
@CADbloke 嗯?我相信它可以! - 41686d6564 stands w. Palestine
如果找不到“.”,则idx == -1,您需要添加一行(最后一行),即零,字符串的开头(https://msdn.microsoft.com/en-us/library/aka44szs(v=vs.110).aspx)。如果没有“.”,它将返回整个字符串。 - CAD bloke
4
确实如此,然而当idx=-1时,s.Substring(0, idx)会抛出异常。我将编辑答案并添加一个if语句来表明这一点。 - Phil K

15

你也可以使用一点LINQ。前面部分有些啰嗦,但后面部分相当简洁:

string input = "My. name. is Bond._James Bond!";

string[] split = input.Split('.');
string firstPart = string.Join(".", split.Take(split.Length - 1)); //My. name. is Bond
string lastPart = split.Last(); //_James Bond!

8
string[] theSplit = inputString.Split('_'); // split at underscore
string firstPart = theSplit[0]; // get the first part
string secondPart = "_" + theSplit[1]; // get the second part and concatenate the underscore to at the front

编辑:根据评论;如果您的输入字符串中只有一个下划线字符,则此方法有效。


9
值得注意的是,只有在字符串中只有一个字母出现一次时,这种方法才能正确地起作用。虽然在这个示例中是正确的,但当提问者在实际应用中使用它时,情况可能并非如此。 - drew_w
只需提供拆分数量,例如 string[] theSplit = inputString.Split(new char[] { '_' }, 2); - Peter Ivan

3
  1. Assuming you only want the split character to appear on the second and greater split strings...
  2. Assuming you want to ignore duplicate split characters...
  3. More curly braces... check...
  4. More elegant... maybe...
  5. More fun... Heck yeah!!

    var s = "My. name. is Bond._James Bond!";
    var firstSplit = true;
    var splitChar = '_';
    var splitStrings = s.Split(new[] { splitChar }, StringSplitOptions.RemoveEmptyEntries)
        .Select(x =>
        {
            if (!firstSplit)
            {
                return splitChar + x;
            }
            firstSplit = false;
            return x;
        });
    

0
皮埃尔-吕克的回答的更简洁版本:
var s = "My. name. is Bond._James Bond!";

if (s.Split(".") is [.. var first, var last])
{
    Console.WriteLine(string.Join(".", first));
    Console.WriteLine(last);
}


明显的缺点是使用相同的字符进行分割和连接的第一部分。如果你只对最后一部分感兴趣,你可以使用is [.., var last]

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