从字符串末尾删除标签的最佳方法是什么?

时间:2020-03-06 14:44:26  来源:igfitidea点击:

我正在使用的.NET Web系统允许最终用户在某些情况下输入HTML格式的文本。在某些地方,我们希望保留所有标记,但去除所有结尾的中断标记(但在文本正文中保留所有中断)。

最好的方法是什么? (我可以想到实现此目的的方法,但我敢肯定它们不是最好的方法。)

解决方案

我们可以使用正则表达式来查找和删除正则表达式匹配项设置为锚定在字符串末尾的文本。

我敢肯定这也不是最好的方法,但是除非我们有尾随空格或者其他东西,否则它应该可以工作。

while (myHtmlString.EndsWith("<br>"))
{
    myHtmlString = myHtmlString.SubString(0, myHtmlString.Length - 4);
}

我们可以使用RegEx或者检查尾随字符串是否为断行并将其删除

正如@Mitch所说的,

//  using System.Text.RegularExpressions;

/// <summary>
///  Regular expression built for C# on: Thu, Sep 25, 2008, 02:01:36 PM
///  Using Expresso Version: 2.1.2150, http://www.ultrapico.com
///  
///  A description of the regular expression:
///  
///  Match expression but don't capture it. [\<br\s*/?\>], any number of repetitions
///      \<br\s*/?\>
///          <
///          br
///          Whitespace, any number of repetitions
///          /, zero or one repetitions
///          >
///  End of line or string
///  
///  
/// </summary>
public static Regex regex = new Regex(
    @"(?:\<br\s*/?\>)*$",
    RegexOptions.IgnoreCase
    | RegexOptions.CultureInvariant
    | RegexOptions.IgnorePatternWhitespace
    | RegexOptions.Compiled
    );
regex.Replace(text, string.Empty);

我们还可以尝试(如果标记可能是有效的树)类似于以下内容:

string s = "<markup><div>Text</div><br /><br /></markup>";

XmlDocument doc = new XmlDocument();
doc.LoadXml(s);

Console.WriteLine(doc.InnerXml);

XmlElement markup = doc["markup"];
int childCount = markup.ChildNodes.Count;
for (int i = childCount -1; i >= 0; i--)
{
    if (markup.ChildNodes[i].Name.ToLower() == "br")
    {
        markup.RemoveChild(markup.ChildNodes[i]);
    }
    else
    {
        break;
    }
}
Console.WriteLine("---");
Console.WriteLine(markup.InnerXml); 
Console.ReadKey();

上面的代码有点"草稿",但是如果我们将其剪切并粘贴到控制台应用程序中并运行它,则它确实可以工作:=)

我试图忽略我们原始问题中的歧义,并按字面意义进行阅读。这是使TrimEnd重载以获取字符串的扩展方法。

static class StringExtensions
{
    public static string TrimEnd(this string s, string remove)
    {
        if (s.EndsWith(remove))
        {
            return s.Substring(0, s.Length - remove.Length);
        }
        return s;
    }
}

以下是一些测试表明它可以正常工作:

Debug.Assert("abc".TrimEnd("<br>") == "abc");
        Debug.Assert("abc<br>".TrimEnd("<br>") == "abc");
        Debug.Assert("<br>abc".TrimEnd("<br>") == "<br>abc");

我想指出的是,此解决方案比regex更易于阅读,可能比regex更快(如果我们担心性能,则应使用探查器,而不应该进行推测),并且对于从字符串末尾删除其他内容很有用。

如果问题比我们说的更笼统(例如,如果我们要删除&lt;BR>&lt;/BR>并处理尾随空格或者其他任何内容,则regex会更合适。

对bdukes代码进行少量更改,因为它不会回溯,因此应该更快。

public static Regex regex = new Regex(
    @"(?:\<br[^>]*\>)*$",
    RegexOptions.IgnoreCase
    | RegexOptions.CultureInvariant
    | RegexOptions.IgnorePatternWhitespace
    | RegexOptions.Compiled
);
regex.Replace(text, string.Empty);