C#中如何通过索引检索提取所有匹配的文本片段
现有代码存在的问题
- 调用
IndexOf时未指定检索起始位置,默认每次都从文本开头查找,匹配到第一个符合条件的片段后就停止检索,无法获取后续匹配内容 StringBuilder实例定义在读取流的循环内部,每次循环都会重置已拼接的内容,即使匹配到多段内容也会被覆盖- 外层
while (!streamReader.EndOfStream)循环无实际意义:ReadToEnd()会一次性读取流的全部内容,执行一次后就会到达流末尾 Substring方法传参错误:该方法第二个参数为待截取的字符长度,原代码直接传入结束符的索引值,会导致截取长度错误,甚至触发字符串越界异常
修改实现
核心逻辑是循环匹配:每找到一组符合规则的片段,就将下一次检索的起始位置移动到当前匹配片段的结束符之后,持续检索直到文本末尾,修改后的完整代码如下:
// 一次性读取全部文本内容,无需嵌套循环 string allLines = streamReader.ReadToEnd(); StringBuilder builder = new StringBuilder(); // 初始化检索起始位置 int currentSearchPos = 0; while (true) { // 从当前检索位置向后查找起始关键词"color" int startIndex = allLines.IndexOf("color", currentSearchPos); // 找不到起始关键词则终止循环 if (startIndex == -1) break; // 从起始关键词位置向后查找最近的结束符"}" int endIndex = allLines.IndexOf("}", startIndex); // 找不到对应结束符则终止循环 if (endIndex == -1) break; // 计算截取长度,提取匹配片段,+1是为了把结束符"}"也包含在结果中 string matchContent = allLines.Substring(startIndex, endIndex - startIndex + 1); builder.AppendLine(matchContent); // 更新检索起始位置到当前结束符之后,避免重复匹配 currentSearchPos = endIndex + 1; } // 将所有匹配结果赋值给文本框 textBox1.Text = builder.ToString();
可选调整说明
- 如果不需要在提取结果中保留结束符
},截取长度计算时去掉+1即可 - 如果需要忽略关键词大小写匹配,可以给
IndexOf传入第三个参数StringComparison.OrdinalIgnoreCase - 如果待处理文本存在
{}嵌套结构,当前逻辑会匹配离起始关键词最近的}作为结束,需要支持嵌套的话要额外添加括号层级计数逻辑
内容的提问来源于stack exchange,提问作者JOHN SMITH
相关产品推荐
相关产品推荐

