字符串提取编译错误:从含转义字符的code中提取指定区间数据
解决控制字符区间提取与编译错误问题
首先,你的代码编译报错的核心原因是非法的Unicode转义序列:你写的"\u000" + i完全无效——C#要求\u后面必须跟4位十六进制数字,\u000只有3位,编译器直接就会报错。这是第一个要解决的问题。
接下来,我们一步步解决你的需求:提取\u0001与\u0002、\u0002与\u0003之间的ABC、DEF、GHI等内容。
步骤1:修正控制字符的引用方式
别用字符串拼接生成控制字符,直接用对应的字符值就行:
\u0001等价于(char)1(或(char)0x01)\u0002等价于(char)2(或(char)0x02)- 以此类推
这样既避免了编译错误,也能精准定位目标控制字符的位置。
步骤2:正确截取控制字符间的片段
你的原字符串里多次出现\u0001,所以得找到目标内容前的最后一个对应控制字符,再定位下一个结束控制字符的位置,之后截取中间内容。
步骤3:从片段中提取目标字母序列
截取到中间片段后,用正则表达式匹配\后面的大写字母序列(比如\ABC01里的ABC)就可以拿到想要的内容。
完整示例代码
using System; using System.Text.RegularExpressions; class Program { static void Main() { // 修正原字符串的非法转义:把\DEF改为\\DEF,确保符合C#语法 string code = "\0\u0001\0\0\0????\u0001\0\0\0\0\0\0\0\u000f\u0001\0\0\0\u001f\u0001\\ABC01\0\0\0\u001f\0\0\0\u0002\\DEF01\0\0\0\u001f\0\0\0\u0003\\\\GHI01\0\0\0\u001f\0\0\0"; // 处理1-2、2-3两个区间 for (int i = 1; i <= 2; i++) { char startMarker = (char)i; char endMarker = (char)(i + 1); // 找到结束标记前的最后一个起始标记,避免匹配到前面无关的同标记 int endPos = code.IndexOf(endMarker); int startIndex = endPos == -1 ? -1 : code.LastIndexOf(startMarker, endPos); if (startIndex == -1) { Console.WriteLine($"未找到起始标记\\u000{i}"); continue; } // 截取两个标记之间的内容 string segment = code.Substring(startIndex + 1, endPos - startIndex - 1); // 提取\后面的连续大写字母 Match match = Regex.Match(segment, @"\\([A-Z]+)"); if (match.Success) { Console.WriteLine($"提取结果:{match.Groups[1].Value}"); } else { Console.WriteLine($"未在片段中找到目标序列"); } } } }
代码说明
- 修正字符串转义:原字符串里的
\DEF会被编译器识别为非法转义(\D不是合法转义字符),所以改为\\DEF,表示实际字符串中的\DEF。 - 精准定位标记:用
LastIndexOf(startMarker, endPos)确保找到的起始标记是在结束标记之前的最后一个,避开前面无关的\u0001。 - 正则提取目标:
@"\\([A-Z]+)"匹配字符串中的\,然后捕获后面的连续大写字母,正好提取出ABC、DEF、GHI。
关于IndexOf处理\的问题
你提到字符串包含\时IndexOf返回-1,大概率是查找时没正确转义:
- 在C#字符串中,单个
\需要写成\\,所以查找时应该用code.IndexOf('\\')或者code.IndexOf(@"\"),而不是code.IndexOf("\")(这会直接编译报错)。
内容的提问来源于stack exchange,提问作者Atom99
相关产品推荐
相关产品推荐

