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

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

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

当前回答

除了马丁·布朗的回答,我也有一个关于数字的问题。例如:“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]。

其他回答

我知道这是一个旧的,但这是一个扩展我使用当我需要这样做:

public static class Extensions
{
    public static string ToSentence( this string Input )
    {
        return new string(Input.SelectMany((c, i) => i > 0 && char.IsUpper(c) ? new[] { ' ', c } : new[] { c }).ToArray());
    }
}

这将允许您使用MyCasedString.ToSentence()

replaceAll("(?<=[^^\\p{Uppercase}])(?=[\\p{Uppercase}])"," ");

下面是在SQL中如何做到这一点

create  FUNCTION dbo.PascalCaseWithSpace(@pInput AS VARCHAR(MAX)) RETURNS VARCHAR(MAX)
BEGIN
    declare @output varchar(8000)

set @output = ''


Declare @vInputLength        INT
Declare @vIndex              INT
Declare @vCount              INT
Declare @PrevLetter varchar(50)
SET @PrevLetter = ''

SET @vCount = 0
SET @vIndex = 1
SET @vInputLength = LEN(@pInput)

WHILE @vIndex <= @vInputLength
BEGIN
    IF ASCII(SUBSTRING(@pInput, @vIndex, 1)) = ASCII(Upper(SUBSTRING(@pInput, @vIndex, 1)))
       begin 

        if(@PrevLetter != '' and ASCII(@PrevLetter) = ASCII(Lower(@PrevLetter)))
            SET @output = @output + ' ' + SUBSTRING(@pInput, @vIndex, 1)
            else
            SET @output = @output +  SUBSTRING(@pInput, @vIndex, 1) 

        end
    else
        begin
        SET @output = @output +  SUBSTRING(@pInput, @vIndex, 1) 

        end

set @PrevLetter = SUBSTRING(@pInput, @vIndex, 1) 

    SET @vIndex = @vIndex + 1
END


return @output
END

以下是我的解决方案,基于Binary Worriers的建议和Richard Priddys的评论,但也考虑到空白可能存在于提供的字符串中,所以它不会在现有空白旁边添加空白。

public string AddSpacesBeforeUpperCase(string nonSpacedString)
    {
        if (string.IsNullOrEmpty(nonSpacedString))
            return string.Empty;

        StringBuilder newText = new StringBuilder(nonSpacedString.Length * 2);
        newText.Append(nonSpacedString[0]);

        for (int i = 1; i < nonSpacedString.Length; i++)
        {
            char currentChar = nonSpacedString[i];

            // If it is whitespace, we do not need to add another next to it
            if(char.IsWhiteSpace(currentChar))
            {
                continue;
            }

            char previousChar = nonSpacedString[i - 1];
            char nextChar = i < nonSpacedString.Length - 1 ? nonSpacedString[i + 1] : nonSpacedString[i];

            if (char.IsUpper(currentChar) && !char.IsWhiteSpace(nextChar) 
                && !(char.IsUpper(previousChar) && char.IsUpper(nextChar)))
            {
                newText.Append(' ');
            }
            else if (i < nonSpacedString.Length)
            {
                if (char.IsUpper(currentChar) && !char.IsWhiteSpace(nextChar) && !char.IsUpper(nextChar))
                {
                    newText.Append(' ');
                }
            }

            newText.Append(currentChar);
        }

        return newText.ToString();
    }

这个问题有点老了,但现在在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"