在C#中用大写字母拆分字符串的最佳方法是什么?
示例:
HelloStackOverflow Users.How你在做什么?
预期结果:
Hello Stack Overflow Users。你好吗?
答案 0 :(得分:2)
您可以使用正则表达式:
static readonly Regex splitter = new Regex(@"\s+|(?=\s*[A-Z]+)|(?<=[,.?!])");
var spacedOut = splitter.Replace(str, " ");
这使用前瞻来匹配大写字母前的点(用\s*
来吞下空格)。
在标点符号后,它使用lookbehind来匹配斑点。
答案 1 :(得分:2)
这取决于你如何定义“最佳”。
除非你想要一个简单的实现(盲目地在每个大写字母前面插入一个空格),否则我会避免使用正则表达式并只编写几行代码来完全按照我的需要进行操作 - 创建一个目标StringBuilder,做一个foreach通过字符串的字符,复制字符并在适当的时候插入额外的空格 - 你只需要保留一个状态变量来知道前一个字符是否为大写。这样可以轻松处理所有可能的特殊情况(第一个字符是大写,首字母缩略词,标点符号或空格后的字符,单词如“A”,文化敏感处理等)。
为什么我不使用正则表达式?
首先,如果你想要很好地处理所有特殊情况,你可能需要相当优秀的正则表达式技能,结果将是一个难以理解的“魔术字符串”(难以阅读/维护,如完美演示@Slaks恕我直言 - 你可以在10秒内阅读并理解他的正则表达方式吗?)。一个简单的循环将更容易编写,测试,调试,读取和升级,除非您(以及将来可能必须阅读/维护您的代码的任何其他人)多年来一直在使用正则表达式。
其次,通过字符循环非常简单。由于它提供的更高级别的泛化,正则表达式几乎肯定会更慢。这对您来说可能是也可能不是问题,但在确定“最佳”时效率可能是一个重要因素。
第三,我是一只老狗,我没有看到使用聪明的新技巧来解决简单的for循环可以处理的问题:-) ...我常常看到程序员使用“酷” “模糊的LINQ查询和正则表达式取代了一个简单的2或3线循环,它让我想到了一个古老的格言”对于一个有锤子的男人,一切看起来像钉子“。正如所有工具一样,正则表达式占有一席之地。而且我不相信这证明了任何复杂的事情。
答案 2 :(得分:0)
我是一个老派的家伙,我会用StringBuilder
来写,因为我不会说英语:
var sb = new StringBuilder(input.Length);
int nextIndexToAdd = 0;
for (int i = 1; i < input.Length;i++ )
if (char.IsUpper(input[i])
&& !char.IsWhiteSpace(input[i - 1])
&& (!char.IsUpper(input[i - 1]) || (i < input.Length - 1 && !char.IsUpper(input[i + 1]))))
{
sb.Append(input.Substring(nextIndexToAdd, i - nextIndexToAdd));
sb.Append(" ");
nextIndexToAdd = i;
}
sb.Append(input.Substring(nextIndexToAdd));
string result = sb.ToString();
这会同时处理IAmFromUSA
和HelloStack...