C# 按感叹号拆分字符串时忽略引号内分隔符的实现问题
C# 带引号内容的字符串拆分实现
需求为仅以不在双引号包裹范围内的!作为分隔符拆分字符串,两个可行方案如下:
方案1:自定义状态机遍历实现(推荐,性能更高、可扩展性强)
核心逻辑是遍历字符串时标记当前是否处于双引号内部,仅当不在引号内的!才判定为分隔符,代码示例:
using System; using System.Collections.Generic; using System.Text; public static class StringSplitter { /// <param name="trimEntries">是否移除分段前后的空白字符</param> public static List<string> SplitOutsideQuotes(string input, char separator, bool trimEntries = true) { var result = new List<string>(); if (string.IsNullOrEmpty(input)) return result; var currentPart = new StringBuilder(); bool inQuotes = false; foreach (char c in input) { if (c == '"') { inQuotes = !inQuotes; currentPart.Append(c); continue; } if (c == separator && !inQuotes) { // 命中分隔符,结束当前分段 var part = trimEntries ? currentPart.ToString().Trim() : currentPart.ToString(); if (!string.IsNullOrEmpty(part)) { result.Add(part); } currentPart.Clear(); // 若明确只需要拆分为两部分,此处可加判断:result.Count == 1时,直接把剩余字符全部加入currentPart后跳出循环 continue; } currentPart.Append(c); } // 加入最后一段内容 var lastPart = trimEntries ? currentPart.ToString().Trim() : currentPart.ToString(); if (!string.IsNullOrEmpty(lastPart)) { result.Add(lastPart); } return result; } } // 调用示例 public static void Main() { string input = "\"Hello, World!\" ! \"Some other string\""; var splitResult = StringSplitter.SplitOutsideQuotes(input, '!'); // 输出结果: // 索引0: "Hello, World!" // 索引1: "Some other string" foreach (var part in splitResult) { Console.WriteLine(part); } }
如果场景存在转义双引号(比如\"),仅需新增变量标记当前字符是否为转义字符,调整引号判定逻辑即可适配。
方案2:正则表达式实现(代码更简洁)
通过正则匹配跳过引号内部的内容,直接匹配拆分后的有效分段,代码示例:
using System; using System.Collections.Generic; using System.Text.RegularExpressions; public static void Main() { string input = "\"Hello, World!\" ! \"Some other string\""; var matches = Regex.Matches(input, @"""[^""]*""|[^!]+"); var splitResult = new List<string>(); foreach (Match match in matches) { var part = match.Value.Trim(); if (!string.IsNullOrEmpty(part)) { splitResult.Add(part); } } // 输出结果和方案1一致 foreach (var part in splitResult) { Console.WriteLine(part); } }
正则说明:"[^"]*"匹配完整的双引号包裹内容,[^!]+匹配所有非!的连续字符,二者取或即可自动忽略引号内部的!。
内容的提问来源于stack exchange,提问作者Bob Ross
相关产品推荐
相关产品推荐

