Skip to content

Instantly share code, notes, and snippets.

@JimBobSquarePants
Created October 13, 2021 13:45
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save JimBobSquarePants/f6a410ecd1bb9ac54a6d03673325ab7b to your computer and use it in GitHub Desktop.
Add spaces to string based upon the position of Uppercase letters
/// <summary>
/// Returns the input string with spaces inserted at each uppercase character.
/// </summary>
/// <param name="input">The input string to split.</param>
/// <returns>The <see cref="string"/>.</returns>
public static string ToSplitTitleString(string input)
{
int spaces = 0;
Rune whitespace = new(0x0020);
Rune previous = default;
foreach (Rune rune in input.EnumerateRunes())
{
if (previous != default && Rune.IsUpper(rune) && !Rune.IsWhiteSpace(previous))
{
spaces++;
}
previous = rune;
}
if (spaces == 0)
{
return input;
}
unsafe
{
// Create the new string in an efficient manner by padding out a new span and copying the runes across.
fixed (char* inputPtr = input)
{
return string.Create(input.Length + (spaces * whitespace.Utf16SequenceLength), (Ptr: (IntPtr)inputPtr, input.Length), (chars, args) =>
{
ReadOnlySpan<char> source = new((char*)args.Ptr, args.Length);
Span<char> destination = chars;
previous = default;
int i = 0;
foreach (Rune rune in source.EnumerateRunes())
{
if (previous != default && Rune.IsUpper(rune) && !Rune.IsWhiteSpace(previous))
{
// Insert a space before the uppercase rune.
whitespace.EncodeToUtf16(chars.Slice(i));
i += whitespace.Utf16SequenceLength;
}
rune.EncodeToUtf16(chars.Slice(i));
i += rune.Utf16SequenceLength;
previous = rune;
}
});
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment