-
-
Save vkobel/d7302c0076c64c95ef4b to your computer and use it in GitHub Desktop.
public static class ExtensionMethods { | |
public static string ToUnderscoreCase(this string str) { | |
return string.Concat(str.Select((x, i) => i > 0 && char.IsUpper(x) ? "_" + x.ToString() : x.ToString())).ToLower(); | |
} | |
} |
thx
arguably should convert IOStream
to io_stream
, but makes it i_o_stream
instead.
Package Humanizer.Core solved my use case (with its string.Underscore
extension method)
Thanks ♥
Very handy, thanks!
thanks!
Very thanks!
Can you please help me change this in a way so IBTest
becomes ib_test
not i_b_test
?
I think I found my answer from 'UseSnakeCaseNamingConvention` from EF Core codebase.
public static string ToSnakeCase(this string name)
{
if (string.IsNullOrEmpty(name))
return name;
var builder = new StringBuilder(name.Length + Math.Min(2, name.Length / 5));
var previousCategory = default(UnicodeCategory?);
for (var currentIndex = 0; currentIndex < name.Length; currentIndex++)
{
var currentChar = name[currentIndex];
if (currentChar == '_')
{
builder.Append('_');
previousCategory = null;
continue;
}
var currentCategory = char.GetUnicodeCategory(currentChar);
switch (currentCategory)
{
case UnicodeCategory.UppercaseLetter:
case UnicodeCategory.TitlecaseLetter:
if (previousCategory == UnicodeCategory.SpaceSeparator ||
previousCategory == UnicodeCategory.LowercaseLetter ||
previousCategory != UnicodeCategory.DecimalDigitNumber &&
previousCategory != null &&
currentIndex > 0 &&
currentIndex + 1 < name.Length &&
char.IsLower(name[currentIndex + 1]))
{
builder.Append('_');
}
currentChar = char.ToLower(currentChar);
break;
case UnicodeCategory.LowercaseLetter:
case UnicodeCategory.DecimalDigitNumber:
if (previousCategory == UnicodeCategory.SpaceSeparator)
builder.Append('_');
break;
default:
if (previousCategory != null)
previousCategory = UnicodeCategory.SpaceSeparator;
continue;
}
builder.Append(currentChar);
previousCategory = currentCategory;
}
return builder.ToString();
}
This improved method solved the mentioned problems in the comments:
public static class ExtensionMethods
{
public static string ToUnderscoreCase(this string str) =>
string.Concat(str.Select((x, i) => (i > 0 && char.IsUpper(x) && (char.IsLower(str[i - 1]) || char.IsLower(str[i + 1])))
? "_" + x.ToString() : x.ToString())).ToLower();
}
public static string ToUnderscoreCase(this string str) =>
string.Concat(str.Select((x, i) => (i > 0 && char.IsUpper(x) && (char.IsLower(str[i - 1]) || char.IsLower(str[i + 1])))
? "_" + x.ToString() : x.ToString())).ToLower();
This causes an exception with "abcDeFG".
Here the corrected method:
static string ToUnderscoreCase(this string str) =>
string.Concat(
str.Select((x, i) =>
i > 0 && char.IsUpper(x) && (char.IsLower(str[i - 1]) || i < str.Length - 1 && char.IsLower(str[i + 1]))
? "_" + x
: x.ToString())).ToLowerInvariant();
Easy on eyes solution with custom separator:
public static string ToLowerBySep(this string source, char sep)
{
var result = new List<char>();
var chars = source.Replace(" ", "").ToCharArray();
for (var i = 0; i < chars.Length; i++)
{
if (i != 0 && char.IsUpper(chars[i]))
{
result.Add(sep);
}
result.Add(chars[i]);
}
return string.Concat(result).ToLowerInvariant();
}
Thank you :)