如何从字符串末尾删除后缀?

57

我想要:

  1. 检查一个变量,并确定它的最后两个字符是否为“Id”
  2. 如果是,就把它们删除。

我可以用下面这段代码来实现,但如果字符串中其他地方也有“Id”子串,那么它就会出错。有没有一种 RemoveFromEnd() 方法可以接受一个字符数量参数?

 if (column.EndsWith("Id"))
 {
       //remove last 2 characters
       column = column.replace("Id", "");
 }

我看到这个解决方案,它可以做到这个:

column = System.Text.RegularExpressions.Regex.Replace(column, "Id$", "");

但是它说它很慢,而且我将在一个代码块中运行这段代码,希望它非常快,因此我想看看是否有更快的解决方案。


只是好奇正则表达式有多“慢”(没有回溯的末端锚应该非常快)......尽管在这里子字符串可能更合适。另一方面,使用正则表达式就没有显式的条件/EndsWith。 - user166390
正则表达式在一般情况下应该更快。您尝试过预编译它或将其存储为成员变量以在方法中使用吗?(以避免每次创建正则表达式的成本) - jdehaan
可能是截取字符串末尾的空格的重复问题。 - nawfal
1
如果输入字符串为"MyIdWrongId",则您放置的代码片段将从字符串中删除所有作为后缀的"Id",它将返回"MyWrong"。 - Roberto
7个回答

97

String.Substring可以实现这个功能:

column = column.Substring(0, column.Length - 2);
你可以使用它来自己编写RemoveFromEnd:
public static string RemoveFromEnd(this string s, string suffix)
{
    if (s.EndsWith(suffix))
    {
        return s.Substring(0, s.Length - suffix.Length);
    }

    return s;
}

如果你不想使用正则表达式,我同意这种方法。但是,真的吗,这样会更快吗? - DOK
1
@DOK:.NET 中的字符串操作方法非常高效。对于像这样的简单操作,我经常发现它们比正则表达式快得多。 - Fredrik Mörk
考虑到正则表达式的启动成本?如果正则表达式在这方面更快,我会感到非常惊讶。 - Jim Mischel
8
可以修改为一行代码:return s.EndsWith(suffix) ? s.Substring(0, s.Length - suffix.Length) : s; 该行代码的功能是判断字符串s是否以suffix结尾,如果是,则返回除去suffix后的s,否则返回原始的s。 - aggaton
需要一个 TrimEnd(this string, string, string) 等等 :) - bambams
显示剩余2条评论

17

使用 System.Text.RegularExpressions 中的 Regex.Replace 方法是 SubString 方法的一种替代方案:

using System.Text.RegularExpressions;
...
column = Regex.Replace(column, @"Id$", String.Empty);

这种方法可以避免测试,但我不确定它是否真的会有速度优势。至少在某些情况下它可能是有用的替代方案,例如需要同时检查多个条件的情况。

可以编译正则表达式并重复使用以获得一些性能提升,并且可以代替调用静态方法使用,如下所示:

// stored as a private member
private static Regex _checkId = new Regex(@"Id$", RegexOptions.Compiled);
...
// inside some method
column = _checkId.Replace(column, String.Empty);

1
你曾经比较过编译正则表达式和 EndsWith-Substring 吗? - Shimmy Weitzhandler

6

如果您自己编写代码,可以添加一个 RemoveFromEnd() 方法:

public static string RemoveFromEnd(this string str, string toRemove)
{
    if (str.EndsWith(toRemove))
        return str.Substring(0, str.Length - toRemove.Length);
    else
        return str;
}

您可以按照以下方式使用它:
column = column.RemoveFromEnd("Id");

4

既然您已经知道要删除的部分的长度,您可以使用Substring函数:

if (column.EndsWith("Id"))
{    
    column = column.Substring(0, column.Length - 2);
}

如果最后两个字符不是"Id",则这将错误地删除它们。 - DOK
1
@DOK:当然,这是打算放在if块内的(而不是OP中的Replace调用)。为了清晰起见,将添加if块。 - Fredrik Mörk

1

试试这个:

if (column.IndexOf("Id") == column.Length-2) {
    column = column.Substring(0, column.Length-2);
}

1

随着 C# 8 中引入的(相对)新的 范围语法,您甚至可以进一步简化 RemoveEnd 方法:

public static string RemoveFromEnd(this string s, string suffix)
{
    if (s.EndsWith(suffix))
    {
        return s[..^suffix.Length];
    }

    return s;
}

0

补充一下@Jon的回答:

你想要不区分大小写地执行这个操作吗?

if (column.ToLower().EndsWith("id")) { column = column.Remove(column.Length - 2); }

如果ID在字符串中是唯一的,并且需要始终被删除...
 #No if check....
 column = column.Replace("Id", "");

如果它是不区分大小写的并且只出现一次,我仍然会使用第一个检查。

-1;这不通过Turkey Test。对于大多数情况来说,这可能仍然可以使用(因为大多数代码不需要在土耳其语环境下运行),但对于某些读者来说,这段代码实际上是有问题的。 - Mark Amery

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