C#从字符串末尾删除子字符串

61

我有一个字符串数组:

string[] remove = { "a", "am", "p", "pm" };

我有一个文本框,用户在其中输入文本。如果他们在文本框中输入remove数组中的任何字符串,该字符串都应被删除。最简单的方法是什么?

编辑 为了澄清,我正在制作一个时间解析器。当你给函数一个字符串时,它会尽力将其解析成这种格式:08:14pm。我有一个文本框来测试它。当焦点离开文本框时,我需要获取没有am / pm / a / p后缀的文本,以便只解析数字部分。


1
什么时候应该将其删除?显然,您正在尝试解决时间问题。也许有更好的方法来完全解决您的问题。 - Joe Phillips
当文本框失去焦点时,触发OnLeave事件。 - Entity
1
为什么你想要做这件事?使用泛型列表。 - Shahin
@TheAdam - 你是不是指的是模糊效果? - Jack Marchetti
@Jack 嗯...是的。每当文本框失去焦点时。 - Entity
2
但是你不能只是简单地去除上午/下午指示符,对吗?因为08:14pm != 08:14,而是等于20:14? - Anders Fjeldstad
8个回答

112
string[] remove = { "a", "am", "p", "pm" };
string inputText = "blalahpm";

foreach (string item in remove)
    if (inputText.EndsWith(item))
    {
        inputText = inputText.Substring(0, inputText.LastIndexOf(item));
        break; //only allow one match at most
    }

太好了!谢谢!(它让我等待5分钟才能将其标记为答案,不知道为什么...) - Entity
4
对于最初的问题,正确的答案是:如果用户写了08:14pm,那么她的意思是20:14。一旦去掉AM/PM标识符,你就无法确定时间应该解析为12小时制还是24小时制。 - Anders Fjeldstad
2
如果用户输入了“08:14pm”,那么程序将保留原样。如果他们输入了“814pm”,则程序需要去掉上午/下午部分,以便只处理数字部分。在放回文本框之前,再将其添加回去。 - Entity
LastIndexOf调用可以被简单的数学计算替代,因为我们无论如何都会检查item是否在字符串末尾:inputText = inputText.Substring(0, inputText.Length - input.Length)。但对我来说,最好的方式是使用C# 8中的索引和范围:inputText = inputText[..^item.Length] - Mariusz Pawelski

39
foreach (string suffix in remove)
{
    if (yourString.EndsWith(suffix))
    {
        yourString = yourString.Remove(yourString.Length - suffix.Length);
        break;
    }
}

10
这种方法比被接受的答案更有效,因为它不需要两次搜索子字符串。 - Duncan Lukkenaer

11
我认为BrokenGlass的解决方案很好,但我个人更喜欢创建三个单独的方法,允许用户仅修剪开头、结尾或两者都修剪。
如果这些修剪方法将经常使用,我会将它们创建为帮助类和/或扩展方法;http://msdn.microsoft.com/en-gb/library/vstudio/bb383977.aspx
public string TrimStart(string inputText, string value, StringComparison comparisonType = StringComparison.CurrentCultureIgnoreCase)
{
    if (!string.IsNullOrEmpty(value))
    { 
        while (!string.IsNullOrEmpty(inputText) && inputText.StartsWith(value, comparisonType))
        {
            inputText = inputText.Substring(value.Length - 1);
        }
    }

    return inputText;
}

public string TrimEnd(string inputText, string value, StringComparison comparisonType = StringComparison.CurrentCultureIgnoreCase)
{
    if (!string.IsNullOrEmpty(value))
    {
        while (!string.IsNullOrEmpty(inputText) && inputText.EndsWith(value, comparisonType))
        {
            inputText = inputText.Substring(0, (inputText.Length - value.Length));
        }
    }

    return inputText;
}

public string Trim(string inputText, string value, StringComparison comparisonType = StringComparison.CurrentCultureIgnoreCase)
{
    return TrimStart(TrimEnd(inputText, value, comparisonType), value, comparisonType);
}

使用这些方法,我们可以修改循环遍历包含需要修剪的字符串数组的代码。
var content = "08:00 AM";
var removeList = new [] { "a", "am", "p", "pm" };

for (var i = 0; i < removeList.length; i++)
{
    content = TrimEnd(content, removeList[i]);
}

注意:这段代码可以进一步优化,但是在现状下可以正常工作并且速度不错。


6
我建议将它们制作为扩展方法(使用“this string inputText”作为第一个参数),并默认不区分大小写,因为C#默认区分大小写。 - bradlis7

4

4
char[] remove = { 'a', 'p', 'm' };
string s = "8:14pm";

s = s.TrimEnd(remove);

3
这将把“8:14pamm”更改为“8:14”,这不是原帖作者想要的。 - Daniel Rose
@DanielRose: 我认为这正是OP所要求的。"如果他们在文本框末尾的删除数组中键入任何字符串,它应该被删除。"以及:"我需要获取没有am/pm/a/p后缀的文本。" OP具体询问如何只获取“8:14” - ulty4life
OP要求从末尾删除am/pm(或缩写为a/p)。如果用户输入(更好的例子)“8:14mmmm”,则您的解决方案将返回“8:14”。但我认为该字符串无效,因为“mmm”不是有效的时间指定。 - Daniel Rose
1
哇,七年过去了,但回答仍然解决了问题,却被踩了。太苛刻了。 - ulty4life

2
听起来这是正则表达式的好地方。
using System.Text.RegularExpressions;

public bool IsValidTime(string thetime)
{
  Regex checktime = new Regex(@"^(20|21|22|23|[01]\d|\d)(([:][0-5]\d){1,2})$");

  return checktime.IsMatch(thetime);
} 

假设您需要以 xx:xx 的格式显示时间。

1
var output = (from x in remove
      where input.EndsWith(x)
     select input.Substring(0, input.Length - x.Length)).FirstOrDefault() ?? input;

1

你可以将 DateTime 作为你的主要类型。

使用 DateTime.TryParse 来读取用户输入的时间。并使用 DateTime.ToString 以任何你需要的格式重新格式化时间。


1
如果确切的格式已知(例如hh:mmtt),DateTime.ParseExact或DateTime.TryParseExact会很方便。 - Anders Fjeldstad

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