C#开发标记编辑器时如何检测作用于光标位置的生效HTML标签
解决方案
现有代码问题
- 数据结构选型错误:向前遍历得到的标签顺序是从光标位置往字符串开头方向,HTML标签是嵌套结构,未闭合的生效标签符合后进先出规则,应该用
Stack<>而不是Queue<>来维护标签匹配逻辑。 - 缺少标签匹配逻辑:没有对向前遍历到的开标签匹配前置的对应闭标签,也没有校验光标后是否存在对应未闭合标签的结束标记。
- 标签提取逻辑有缺陷:没有校验
<和>的先后顺序,可能截取到不符合格式的非标签字符串。
修正后可运行的实现
你可以直接替换原有的GetTags方法,逻辑如下:
public static List<TagType> GetTags(string str, int index) { Stack<TagType> activeTags = new Stack<TagType>(); int currentPos = 0; // 遍历整个字符串,直到超过光标位置,动态维护生效标签栈 while (currentPos < index && currentPos < str.Length) { // 找下一个标签起始符 int tagStart = str.IndexOf('<', currentPos); // 下一个标签在光标之后,直接终止遍历 if (tagStart == -1 || tagStart >= index) break; int tagEnd = str.IndexOf('>', tagStart); if (tagEnd == -1) break; string tagStr = str.Substring(tagStart, tagEnd - tagStart + 1); Tag tag = GetTagFromString(tagStr); if (tag != null) { if (tag.opening) { // 开标签入栈 activeTags.Push(tag.type); } else { // 闭标签和栈顶匹配就出栈 if (activeTags.Count > 0 && activeTags.Peek() == tag.type) { activeTags.Pop(); } } } // 跳到标签结束位置之后 currentPos = tagEnd + 1; } // 栈转列表,顺序从外层到内层和示例要求一致 List<TagType> result = activeTags.Reverse().ToList(); return result; }
实现说明
- 不需要拆分前后两个队列,直接从字符串开头遍历到光标位置,用栈动态维护当前生效的标签:遇到开标签入栈,遇到匹配的闭标签出栈。
- 遍历结束后栈里留存的就是作用在光标位置的所有标签,反转后顺序和你给出的示例输出完全一致。
- 边界兼容:自动过滤不认识的标签、格式错误的标签,不会出现空引用异常。
内容的提问来源于stack exchange,提问作者Dynamic
相关产品推荐
相关产品推荐

