|
|
|
@ -1,4 +1,5 @@ |
|
|
|
using System.Collections.Generic; |
|
|
|
using System.Globalization; |
|
|
|
using System.Security.Cryptography; |
|
|
|
using System.Text; |
|
|
|
using System.Text.RegularExpressions; |
|
|
|
@ -312,6 +313,75 @@ namespace System |
|
|
|
: Regex.Replace(str, "[a-z][A-Z]", m => m.Value[0] + "-" + char.ToLowerInvariant(m.Value[1])); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Converts given PascalCase/camelCase string to snake case.
|
|
|
|
/// Example: "ThisIsSampleSentence" is converted to "this_is_a_sample_sentence".
|
|
|
|
/// https://github.com/npgsql/npgsql/blob/dev/src/Npgsql/NameTranslation/NpgsqlSnakeCaseNameTranslator.cs#L51
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="str">String to convert.</param>
|
|
|
|
/// <returns></returns>
|
|
|
|
public static string ToSnakeCase(this string str) |
|
|
|
{ |
|
|
|
if (string.IsNullOrWhiteSpace(str)) |
|
|
|
{ |
|
|
|
return str; |
|
|
|
} |
|
|
|
|
|
|
|
var builder = new StringBuilder(str.Length + Math.Min(2, str.Length / 5)); |
|
|
|
var previousCategory = default(UnicodeCategory?); |
|
|
|
|
|
|
|
for (var currentIndex = 0; currentIndex < str.Length; currentIndex++) |
|
|
|
{ |
|
|
|
var currentChar = str[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 < str.Length && |
|
|
|
char.IsLower(str[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(); |
|
|
|
} |
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Converts string to enum value.
|
|
|
|
/// </summary>
|
|
|
|
@ -476,4 +546,4 @@ namespace System |
|
|
|
return encoding.GetBytes(str); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|