给定字符串“ThisStringHasNoSpacesButItDoesHaveCapitals”,什么是在大写字母之前添加空格的最好方法。所以结尾字符串是"This string Has No space But It Does Have大写"

下面是我使用正则表达式的尝试

System.Text.RegularExpressions.Regex.Replace(value, "[A-Z]", " $0")

当前回答

没有测试性能,但在linq的一行中:

var val = "ThisIsAStringToTest";
val = string.Concat(val.Select(x => Char.IsUpper(x) ? " " + x : x.ToString())).TrimStart(' ');

其他回答

    private string GetProperName(string Header)
    {
        if (Header.ToCharArray().Where(c => Char.IsUpper(c)).Count() == 1)
        {
            return Header;
        }
        else
        {
            string ReturnHeader = Header[0].ToString();
            for(int i=1; i<Header.Length;i++)
            {
                if (char.IsLower(Header[i-1]) && char.IsUpper(Header[i]))
                {
                    ReturnHeader += " " + Header[i].ToString();
                }
                else
                {
                    ReturnHeader += Header[i].ToString();
                }
            }

            return ReturnHeader;
        }

        return Header;
    }

你拥有的一切都很完美。只需要记住将value重新赋值给这个函数的返回值即可。

value = System.Text.RegularExpressions.Regex.Replace(value, "[A-Z]", " $0");

这个问题有点老了,但现在在Nuget上有一个很好的库,它可以做到这一点,以及许多其他转换到人类可读的文本。

在GitHub或Nuget上检查Humanizer。

例子

"PascalCaseInputStringIsTurnedIntoSentence".Humanize() => "Pascal case input string is turned into sentence"
"Underscored_input_string_is_turned_into_sentence".Humanize() => "Underscored input string is turned into sentence"
"Underscored_input_String_is_turned_INTO_sentence".Humanize() => "Underscored input String is turned INTO sentence"

// acronyms are left intact
"HTML".Humanize() => "HTML"

除了马丁·布朗的回答,我也有一个关于数字的问题。例如:“Location2”或“Jan22”应该分别是“Location2”和“Jan22”。

下面是我的正则表达式,用的是Martin Brown的答案:

"((?<=\p{Ll})\p{Lu})|((?!\A)\p{Lu}(?>\p{Ll}))|((?<=[\p{Ll}\p{Lu}])\p{Nd})|((?<=\p{Nd})\p{Lu})"

这里有几个很好的网站,可以帮助你弄清楚每个部分的意思:

基于Java的正则表达式分析器(但适用于大多数。net正则表达式)

基于动作脚本的分析器

上面的正则表达式不能在动作脚本站点上工作,除非您将所有的\p{Ll}替换为[a-z],将\p{Lu}替换为[a-z],并将\p{Nd}替换为[0-9]。

你的解决方案有一个问题,它在第一个字母T之前放了一个空格,所以你得到

" This String..." instead of "This String..."

要绕开这个问题,请寻找前面的小写字母,然后在中间插入空格:

newValue = Regex.Replace(value, "([a-z])([A-Z])", "$1 $2");

编辑1:

如果你使用@"(\p{Ll})(\p{Lu})",它也会拾取重音字符。

编辑2:

如果你的字符串可以包含首字母缩略词,你可能想使用这个:

newValue = Regex.Replace(value, @"((?<=\p{Ll})\p{Lu})|((?!\A)\p{Lu}(?>\p{Ll}))", " $0");

所以driveisscsiccompatible变成了DriveIsSCSICompatible