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

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

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

当前回答

你的解决方案有一个问题,它在第一个字母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

其他回答

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

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

请确保您没有在字符串的开头放置空格,而是将它们放在连续的大写字母之间。这里的一些答案并没有解决其中的一个或两个问题。除了regex,还有其他方法,但如果你更喜欢使用它,试试这个:

Regex.Replace(value, @"\B[A-Z]", " $0")

\B是一个负的\B,所以它代表一个非单词边界。这意味着模式匹配XYzabc中的“Y”,但不匹配Yzabc或XYzabc。作为一个小奖励,你可以在一个有空格的字符串上使用它,它不会使它们加倍。

这里有一个更彻底的解决方案,它没有在单词前面放空格:

注意:我使用了多个regex(不简洁,但它也可以处理首字母缩略词和单字母单词)

Dim s As String = "ThisStringHasNoSpacesButItDoesHaveCapitals"
s = System.Text.RegularExpressions.Regex.Replace(s, "([a-z])([A-Z](?=[A-Z])[a-z]*)", "$1 $2")
s = System.Text.RegularExpressions.Regex.Replace(s, "([A-Z])([A-Z][a-z])", "$1 $2")
s = System.Text.RegularExpressions.Regex.Replace(s, "([a-z])([A-Z][a-z])", "$1 $2")
s = System.Text.RegularExpressions.Regex.Replace(s, "([a-z])([A-Z][a-z])", "$1 $2") // repeat a second time

In:

"ThisStringHasNoSpacesButItDoesHaveCapitals"
"IAmNotAGoat"
"LOLThatsHilarious!"
"ThisIsASMSMessage"

Out:

"This String Has No Spaces But It Does Have Capitals"
"I Am Not A Goat"
"LOL Thats Hilarious!"
"This Is ASMS Message" // (Difficult to handle single letter words when they are next to acronyms.)

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

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()

受到二元忧虑者答案的启发,我尝试了一下。

结果如下:

/// <summary>
/// String Extension Method
/// Adds white space to strings based on Upper Case Letters
/// </summary>
/// <example>
/// strIn => "HateJPMorgan"
/// preserveAcronyms false => "Hate JP Morgan"
/// preserveAcronyms true => "Hate JPMorgan"
/// </example>
/// <param name="strIn">to evaluate</param>
/// <param name="preserveAcronyms" >determines saving acronyms (Optional => false) </param>
public static string AddSpaces(this string strIn, bool preserveAcronyms = false)
{
    if (string.IsNullOrWhiteSpace(strIn))
        return String.Empty;

    var stringBuilder = new StringBuilder(strIn.Length * 2)
        .Append(strIn[0]);

    int i;

    for (i = 1; i < strIn.Length - 1; i++)
    {
        var c = strIn[i];

        if (Char.IsUpper(c) && (Char.IsLower(strIn[i - 1]) || (preserveAcronyms && Char.IsLower(strIn[i + 1]))))
            stringBuilder.Append(' ');

        stringBuilder.Append(c);
    }

    return stringBuilder.Append(strIn[i]).ToString();
}

测试使用秒表运行10000000次迭代和各种字符串长度和组合。

平均比二进制忧虑者的答案快50%(可能多一点)。