【问题标题】:Removing text between 2 strings删除两个字符串之间的文本
【发布时间】:2019-01-24 06:37:59
【问题描述】:

我尝试在 C# 中编写一个函数来删除两个字符串之间的字符串。像这样:

string RemoveBetween(string sourceString, string startTag, string endTag)

一开始我以为这很容易,但后来我遇到了越来越多的问题

所以这是最简单的情况(所有示例都带有 startTag="Start" 和 endTag="End")

"Any Text Start remove this End between" => "Any Text StartEnd between"

但它也应该能够处理多个而不删除之间的文本:

"Any Text Start remove this End between should be still there Start and remove this End multiple" => "Any Text StartEnd between should be still there StartEnd multiple"

它应该总是用最小的字符串来删除:

"So Start followed by Start only remove this End other stuff" => "So Start followed by StartEnd other stuff"

它还应该尊重标签的顺序:

"the End before Start. Start before End is correct" => "the End before Start. StartEnd is correct"

我尝试了一个不起作用的正则表达式(它无法处理多个):

public string RemoveBetween(string sourceString, string startTag, string endTag)
{
    Regex regex = new Regex(string.Format("{0}(.*){1}", Regex.Escape(startTag), Regex.Escape(endTag)));
    return regex.Replace(sourceString, string.Empty);
}

然后我尝试使用 IndexOf 和 Substring,但我没有看到结束。即使它会起作用,这也不是解决这个问题的最优雅的方法。

【问题讨论】:

    标签: c# string


    【解决方案1】:

    这是string.Remove()的方法

    string input = "So Start followed by Start only remove this End other stuff";
    int start = input.LastIndexOf("Start") + "Start".Length;
    int end = input.IndexOf("End", start);
    string result = input.Remove(start, end - start);
    

    我使用LastIndexOf(),因为可以有多个开始,而您希望拥有最后一个。

    【讨论】:

    • 但这仅在字符串中有一次“开始”和“结束”时才有效。如果有多个(参见示例 2),则它不起作用。建立一个循环也不是小事,因为“开始”和“结束”会留在字符串中。
    • 对,用空格和循环搜索LastIndexOf("Start ")
    【解决方案2】:

    您必须稍微修改您的函数以与 ?RegexOptions.RightToLeft 进行非贪婪匹配以处理所有示例:

        public static string RemoveBetween(string sourceString, string startTag, string endTag)
        {
            Regex regex = new Regex(string.Format("{0}(.*?){1}", Regex.Escape(startTag), Regex.Escape(endTag)), RegexOptions.RightToLeft);
            return regex.Replace(sourceString, startTag+endTag);
        }
    

    【讨论】:

    • 这适用于前两个示例,但不适用于最后一个。
    • 添加 RegexOptions.RightToLeft 将处理最后一种情况(同时仍使用其他 2 个示例)。但我不确定它是否涵盖所有需要的情况。 (例如,不适用于 "So Start followed by End only remove this End other stuff"。)
    • RegexOptions.Singleline 用于. 也可以匹配换行符。
    【解决方案3】:

    你可以用这个:

    public static string Remove(string original, string firstTag, string secondTag)
    {
       string pattern = firstTag + "(.*?)" + secondTag;
       Regex regex = new Regex(pattern, RegexOptions.RightToLeft);
    
       foreach(Match match in regex.Matches(original))
       {
          original = original.Replace(match.Groups[1].Value, string.Empty);
       }
    
       return original;
    }
    

    【讨论】:

    • 这适用于前 2 个示例,但不适用于最后一个示例。你能稍微解释一下代码到底是做什么的吗?
    • 是的,你是对的。此代码搜索原始字符串中的所有匹配项并将其删除,但在第三个示例中失败。让我看看我能不能解决它。
    • @Gener4tor 现在已修复 :)
    • 我很抱歉在文本中说:“开始之前的结束。结束之前的开始是正确的”(我将它添加到上面的示例中)你的代码做了一些奇怪的事情。
    • 标签本身不会被移除。这是故意的吗?
    【解决方案4】:
     string data = "text start this is my text end text";
                string startTag = "start";
                string endTag = "end";
                int startIndex = data.IndexOf(startTag)+ startTag.Length;
                Console.WriteLine(data.Substring(startIndex, data.IndexOf(endTag)-startIndex));
    

    【讨论】:

      【解决方案5】:

      或者您可以尝试使用 LINQ,如显示的 here

      public static string Remove(this string s, IEnumerable<char> chars)
      {
          return new string(s.Where(c => !chars.Contains(c)).ToArray());
      }
      

      【讨论】:

        猜你喜欢
        • 2015-11-10
        • 2017-12-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-23
        • 2016-07-01
        • 2014-09-28
        • 1970-01-01
        相关资源
        最近更新 更多