PascalCase字符串拆分时循环反向及索引越界问题排查
问题解析与解决
一、循环反向工作的原因
你对“删除数组中的单词”的逻辑理解和代码实际执行效果搞反了:
- 数组
a的循环:for (int i = 0; i < index - 1; i++)把第一个单词对应的位置替换成空格,调用Trim()后会去掉这些前导空格,最终保留的是第二个单词——这其实是你预期中“删除第一个单词”的结果,但你误以为这个循环是要删除第二个单词。 - 数组
b的循环:for (int i = index-1; i < b.Length; i++)把第二个单词及之后的位置替换成空格,Trim()后去掉后续空格,最终保留的是第一个单词——这是你预期中“删除第二个单词”的结果,但你搞反了数组a和b的作用。
另外补充:你的遍历代码会导致index的值比实际第一个单词的长度多1。比如输入"SkillName",第一个单词"Skill"长度是4,但index最终会是5——因为遇到第一个大写字母S时,先执行index++(变成1),然后循环末尾又执行一次index++(变成2),后续每个非大写字符都会让index++,直到遇到第二个大写字母N时break,最终index是5。
二、注释代码中b数组报错的原因
string.ToCharArray(int startIndex, int length)的第二个参数是要提取的字符长度,不是结束索引。你写的skillDef.ToCharArray(index, skillDef.Length)会让startIndex + length远大于字符串实际长度(比如字符串长度是9,index是5,5+9=14>9),触发索引越界异常。正确写法应该是:
char[] b = skillDef.ToCharArray(index, skillDef.Length - index);
三、更简洁的实现方案
没必要用复杂的数组操作,直接用以下两种方式就能高效实现PascalCase转带空格的格式:
方法1:遍历插入空格
private string SkillName(string skillDef) { if (string.IsNullOrEmpty(skillDef)) return skillDef; StringBuilder sb = new StringBuilder(); sb.Append(skillDef[0]); for (int i = 1; i < skillDef.Length; i++) { if (char.IsUpper(skillDef[i])) { sb.Append(' '); } sb.Append(skillDef[i]); } return sb.ToString(); }
方法2:正则表达式
using System.Text.RegularExpressions; private string SkillName(string skillDef) { return Regex.Replace(skillDef, @"([a-z])([A-Z])", "$1 $2"); }
这个正则会匹配小写字母后跟大写字母的位置,在中间插入空格,完美适配PascalCase格式转换需求。
内容的提问来源于stack exchange,提问作者user23755236
相关产品推荐
相关产品推荐

