How do I convert a string value in PascalCase (other name is UpperCamelCase) to kebab-case with C#?
e.g. "VeryLongName"
to "very-long-name"
How do I convert a string value in PascalCase (other name is UpperCamelCase) to kebab-case with C#?
e.g. "VeryLongName"
to "very-long-name"
Here is how to do that with a regular expression:
public static class StringExtensions
{
public static string PascalToKebabCase(this string value)
{
if (string.IsNullOrEmpty(value))
return value;
return Regex.Replace(
value,
"(?<!^)([A-Z][a-z]|(?<=[a-z])[A-Z0-9])",
"-$1",
RegexOptions.Compiled)
.Trim()
.ToLower();
}
}
Note: the @RossK92's recommendation about handling numbers has been applied
Here's my solution using Microsoft's capitalization conventions. https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/capitalization-conventions
public static class StringExtensions
{
public static string PascalToKebabCase(this string source)
{
if (source is null) return null;
if (source.Length == 0) return string.Empty;
StringBuilder builder = new StringBuilder();
for (var i = 0; i < source.Length; i++)
{
if (char.IsLower(source[i])) // if current char is already lowercase
{
builder.Append(source[i]);
}
else if (i == 0) // if current char is the first char
{
builder.Append(char.ToLower(source[i]));
}
else if (char.IsDigit(source[i]) && !char.IsDigit(source[i - 1])) // if current char is a number and the previous is not
{
builder.Append('-');
builder.Append(source[i]);
}
else if (char.IsDigit(source[i])) // if current char is a number and previous is
{
builder.Append(source[i]);
}
else if (char.IsLower(source[i - 1])) // if current char is upper and previous char is lower
{
builder.Append('-');
builder.Append(char.ToLower(source[i]));
}
else if (i + 1 == source.Length || char.IsUpper(source[i + 1])) // if current char is upper and next char doesn't exist or is upper
{
builder.Append(char.ToLower(source[i]));
}
else // if current char is upper and next char is lower
{
builder.Append('-');
builder.Append(char.ToLower(source[i]));
}
}
return builder.ToString();
}
}
Test
string[] stringArray = new[]
{
null,
"",
"I",
"IO",
"FileIO",
"SignalR",
"IOStream",
"COMObject",
"WebAPI",
"Windows10",
"WindowsServer2019R2"
};
foreach (var str in stringArray)
{
Console.WriteLine($"{str} --> {str.PascalToKebabCase()}");
}
// Output:
// -->
// -->
// I --> i
// IO --> io
// FileIO --> file-io
// SignalR --> signal-r
// IOStream --> io-stream
// COMObject --> com-object
// WebAPI --> web-api
// Windows10 --> windows-10
// WindowsServer2016R2 --> windows-server-2016-r-2
Here is a way to do it without using Regex:
public static string PascalToKebabCase(this string str)
{
if (string.IsNullOrEmpty(str))
return string.Empty;
var builder = new StringBuilder();
builder.Append(char.ToLower(str.First()));
foreach (var c in str.Skip(1))
{
if (char.IsUpper(c))
{
builder.Append('-');
builder.Append(char.ToLower(c));
}
else
{
builder.Append(c);
}
}
return builder.ToString();
}
You'd have issues with well known abbreviations that use upper case letters. For example: COMObject
. This solution obviously wouldn't work.
This is what I came up with taking bits of code and Regex from others:
var pascalCase = "MyReally-CoolMFAString";
var dashCase = Regex.Replace(pascalCase, @"(?<!^)(?<!-)((?<=\p{Ll})\p{Lu}|\p{Lu}(?=\p{Ll}))", "-$1").ToLower();
Console.WriteLine(dashCase);
The output is:
my-really-cool-mfa-string
Taking inspiration from @InBetween:
public static string PascalToKebabCase(this string str)
{
IEnumerable<char> ConvertChar(char c, int index)
{
if (char.IsUpper(c) && index != 0) yield return '-';
yield return char.ToLower(c);
}
return string.Concat(str.SelectMany(ConvertChar));
}
Taking inspiration from @johnathan-barclay:
string.Concat(str.Select((c, i) => (char.IsUpper(c) && i > 0 ? "-" : "") + char.ToLower(c)));
Here is a shorter solution with Regex.Replace
:
public static class KebabConverter
{
public static string ToKebabCase(this string str)
{
// find and replace all parts that starts with one capital letter e.g. Net
var str1 = Regex.Replace(str, "[A-Z][a-z]+", m => $"-{m.ToString().ToLower()}");
// find and replace all parts that are all capital letter e.g. NET
var str2 = Regex.Replace(str1, "[A-Z]+", m => $"-{m.ToString().ToLower()}");
return str2.TrimStart('-');
}
}
string input = "VeryLongName";
char[] arr = input.ToCharArray();
string output = Convert.ToString( arr[0]);
for(int i=1; i<arr.Length; i++){
if(char.IsUpper(arr[i]))
output = output + "-" + Convert.ToString( arr[i]);
else
output = output + Convert.ToString( arr[i]);
}
Console.WriteLine(output.ToLower());
© 2022 - 2024 — McMap. All rights reserved.