When intercepting a string, you need to record whether or not each tag is closed. If there are still tags not closed at the specified length, you need to disable the tag or delete the unclosed tag. Without considering some situations where tags do not need to be closed, the html start and end tags always appear in pairs. We can traverse the input string and put it into the stack at the beginning of the tag, when an end tag is encountered, an element pops up from the stack. In this way, the tag left in the stack is the tag to be supplemented or deleted.
The following is code implementation. If you have a better method, please give it:
Copy codeThe Code is as follows:
Static char END_SLASH = '/';
/// <Summary>
/// Safe truncation string
/// </Summary>
/// <Param name = "input"> input string </param>
/// <Param name = "length"> truncation length </param>
/// <Param name = "trimHalfTag"> true: truncates a half tag; false: adds a half tag. </param>
/// <Param name = "tagStartChar"> Label Start character </param>
/// <Param name = "tagEndChar"> end character of the tag </param>
/// <Param name = "mustCloseTags"> tag array to be closed </param>
/// <Returns> length string </returns>
Public static string SafeTrim (string input, int length, bool trimHalfTag, char tagStartChar, char tagEndChar, string [] mustCloseTags)
{
If (length <= 0) throw new ArgumentException ("length must be a positive number ");
If (mustCloseTags = null) throw new ArgumentNullException ("mustCloseTags ");
Int inputLen = input. Length;
If (string. IsNullOrEmpty (input) | inputLen <= length) return input;
String result = string. Empty;
// Declare the stack to put tags
Stack <string> tags = new Stack <string> ();
For (int I = 0; I <length; I ++)
{
Char c = input [I];
If (c = tagStartChar)
{
String tag = string. Empty;
Int tagIndex = I + 1;
Bool isTagEnd = false;
Bool isTagNameEnd = false;
Result + = c;
Bool hasMarkTagInStack = false;
While (tagIndex <inputLen)
{
Char tagC = input [tagIndex];
Result + = tagC;
TagIndex ++;
If (tag = string. Empty & tagC = END_SLASH)
{
IsTagEnd = true;
Continue;
}
If (! IsTagNameEnd)
{
If (char. IsLetter (tagC) | char. IsNumber (tagC ))
{
Tag + = tagC;
}
Else
{
IsTagNameEnd = true;
}
}
If (! String. IsNullOrEmpty (tag ))
{
If (isTagNameEnd &&! HasMarkTagInStack)
{
If (isTagEnd)
{
Tags. Pop ();
}
Else
{
Tags. Push (tag );
}
HasMarkTagInStack = true;
}
}
If (isTagNameEnd)
{
If (tagC = tagEndChar)
{
I = tagIndex-1;
Break;
}
}
}
}
Else
{
Result + = c;
}
}
While (tags. Count> 0)
{
String tag = tags. Pop ();
Bool isMustCloseTag = false;
Foreach (string mustCloseTag in mustCloseTags)
{
If (string. Compare (mustCloseTag, tag, true) = 0)
{
IsMustCloseTag = true;
Break;
}
}
If (isMustCloseTag)
{
If (trimHalfTag)
{
Int lastTagIndex = result. LastIndexOf (tagStartChar. ToString () + tag, StringComparison. CurrentCultureIgnoreCase );
Result = result. Substring (0, lastTagIndex );
}
Else
{
Result + = (tagStartChar. ToString () + END_SLASH + tag + tagEndChar );
}
}
}
Return result;
}
Reprinted please keep the link to yukai technical blog