仅在下一个字符为小写字母时,将字符串按大写字母拆分

5

我找到了很多关于如何按大写字母拆分字符串的示例,例如:

"MyNameIsRob" 返回 "My Name Is Rob"

我的情况有所不同...

我想要实现以下内容:

"MyFavouriteChocIsDARKChocalate" 应返回 "My Favourite Choc Is DARK Chocalate"

我能想到的唯一办法是仅在下一个字符为小写字母时才按大写字母拆分字符串。

如何实现?


修改现有的解决方案以满足新需求可能会更容易。您能发布您现有的代码吗? - MarcinJuraszek
3
看看这个类似问题的回答:https://dev59.com/0HA75IYBdhLWcg3wlqET#3216204 - 经过快速测试,它似乎可以达到您的要求。 - MrDustpan
那将是最简单和最直接的方法来完成它。 - ElGavilan
@MrDustpan - 那正是我想要的。 - stoic
4个回答

6
你可以使用正则表达式的lookahead和lookbehind来查找大写字母前面或后面的小写字母并进行替换…
var input = "MyFavouriteChocIsDARKChocalate";
var output = Regex.Replace(input, "(((?<!^)[A-Z](?=[a-z]))|((?<=[a-z])[A-Z]))", " $1");
Console.WriteLine(output);

http://dotnetfiddle.net/cIM6QG


2

如果没有使用正则表达式,你可以尝试这样做:

public static string SplitOnCaps(string s)
http://dotnetfiddle.net/qQIIgX :这是一个网站链接。
using System;
using System.Collections.Generic;
using System.Text;

public class Program
{
    public static void Main()
    {
        /*"MyFavouriteChocIsDARKChocalate" should return "My Favourite Choc Is DARK Chocalate"*/
        var input = "MyFavouriteChocIsDARKChocalate";
        var split = SplitOnCaps(input);
        Console.WriteLine(input + " --> " + split);
        var match = "My Favourite Choc Is DARK Chocalate";

        Console.WriteLine(split == match ? "Match" : "No Match");       
    }

    public static string SplitOnCaps(string s)
    {
        var splits = new List<int>();

        var chars = s.ToCharArray();

        for(var i=1; i<chars.Length-1; i++)
        {
            if (IsCapital(chars[i]) && !IsCapital(chars[i+1]) ||
               IsCapital(chars[i]) && !IsCapital(chars[i-1]))
            {
                splits.Add(i);
            }
        }

        var sb = new StringBuilder();

        var lastSplit = 0;
        foreach(var split in splits)
        {
            sb.Append(s.Substring(lastSplit, split - lastSplit) + " ");
            lastSplit = split;
        }
        sb.Append(s.Substring(lastSplit));

        return sb.ToString();
    }
    public static bool IsCapital(char c)
    {
        var i = (int)c;
        return i>=65 && i<=90;
    }
}

注意:我不精通正则表达式


1
也许经典方法适合你的需求:


private static string[] SplitSpecial(string s)
{
    List<string> tmp = new List<string>();
    int lastindex = 0;
    for (int i = 1; i < s.Length; i++)
        if (Char.IsUpper(s[i]) && (Char.IsLower(s[i - 1]) || (i < s.Length - 1 && Char.IsLower(s[i + 1]))))
        {
            if (i > lastindex)
                tmp.Add(s.Substring(lastindex, i - lastindex));
            lastindex = i;
        }
    tmp.Add(s.Substring(lastindex, s.Length - lastindex));
    return tmp.ToArray();
}

要创建一个单一的字符串,您可以使用 String.Join 函数连接结果数组:
string singleStr = String.Join(" ", SplitSpecial("MyFavouriteChocIsDARKChocalate"));

这样做会不会比提供的正则表达式示例更快?我知道正则表达式有时可能会很慢。 - stoic
根据测试(运行两种方法100万次),我的样本速度快了10倍。 - Dmitry

1

经典方法+使用stringBuilder(如果您处理长字符串,则更有效):

    string str = "MyFavouriteChocIsDARKChocalate";
    System.Text.StringBuilder output = new System.Text.StringBuilder(str.Substring(0,1));

    for (int i = 1; i < str.Length; i++)
    {
        if (Char.IsUpper(str[i]) && (!char.IsUpper(str[i-1]) || (i+1 < str.Length && char.IsLower(str[i+1]))))
        {
            output.Append(" " + str[i]);
        }
        else
        {
            output.Append(str[i]);
        }
    }
    string result = output.ToString();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接