如何在Razor中仅依据长度和位置拆分无分隔符的字符串
Razor 无分隔符固定长度字符串拆分方案
针对你习惯C语言sscanf匹配逻辑的场景,以下两种实现都比重复调用Substring更易维护,也能解决你之前正则无法运行的问题:
方案1:正则表达式(官方推荐,最常用)
你之前正则跑不通大概率是没有在Razor页面引入对应命名空间,完整的cshtml写法如下:
@* 页面顶部先引入正则命名空间,缺少这行会报类型无法识别错误 *@ @using System.Text.RegularExpressions; @{ string input = "342050S"; // 正则规则和你写的sscanf逻辑完全对应:2位数字、2位数字、2位数字、1位字符 var match = Regex.Match(input, @"^(\d{2})(\d{2})(\d{2})([A-Za-z])$"); if (match.Success) { int lat_deg = int.Parse(match.Groups[1].Value); int lat_min = int.Parse(match.Groups[2].Value); int lat_sec = int.Parse(match.Groups[3].Value); char lat_hem = char.Parse(match.Groups[4].Value); // 此处直接使用拆分后的变量即可 } }
规则调整非常方便,比如要修改某段的长度,只需要把对应{n}里的数字改成目标长度即可。
方案2:模拟sscanf的扩展方法(贴合C语言使用习惯)
如果更习惯sscanf的调用方式,可以自己封装一个轻量扩展方法,不需要依赖正则:
首先把下面的扩展方法放到项目的公共类中,或者直接写在Razor页面的@functions块里:
public static class StringScanExtension { public static void Scanf(this string input, string format, params Action<string>[] parsers) { int inputPtr = 0; int parserIdx = 0; for (int i = 0; i < format.Length && parserIdx < parsers.Length; i++) { if (format[i] == '%') { i++; // 读取长度标识 int len = 0; while (char.IsDigit(format[i])) { len = len * 10 + (format[i] - '0'); i++; } // 截取对应长度的字符串并传给解析逻辑 parsers[parserIdx]?.Invoke(input.Substring(inputPtr, len)); inputPtr += len; parserIdx++; } } } }
调用方式和C语言sscanf几乎一致:
@{ int lat_deg = 0, lat_min = 0, lat_sec = 0; char lat_hem = default; string input = "342050S"; input.Scanf("%2d%2d%2d%c", v => lat_deg = int.Parse(v), v => lat_min = int.Parse(v), v => lat_sec = int.Parse(v), v => lat_hem = v[0] ); }
额外说明
两种方案都避免了Substring需要反复计算起始索引的问题,修改拆分规则只需要调整匹配格式即可,维护成本更低。
内容的提问来源于stack exchange,提问作者tj26
相关产品推荐
相关产品推荐

