diff --git a/TJC.StringExtensions.Tests/Cases/CamelCaseExtensionsTests.cs b/TJC.StringExtensions.Tests/Cases/CamelCaseExtensionsTests.cs
index 7ff4e67..0ec33f4 100644
--- a/TJC.StringExtensions.Tests/Cases/CamelCaseExtensionsTests.cs
+++ b/TJC.StringExtensions.Tests/Cases/CamelCaseExtensionsTests.cs
@@ -46,4 +46,18 @@ public void SplitCamelCase_FirstLetterUppercase_SplitsWithSpace()
// Assert
Assert.AreEqual(expected, result);
}
+
+ [TestMethod]
+ public void ToCamelCaseTest()
+ {
+ // Arrange
+ var input = "Camel Case Extensions";
+ var expected = "camelCaseExtensions";
+
+ // Act
+ var result = input.ToCamelCase();
+
+ // Assert
+ Assert.AreEqual(expected, result);
+ }
}
\ No newline at end of file
diff --git a/TJC.StringExtensions.Tests/Cases/KebabCaseExtensionsTests.cs b/TJC.StringExtensions.Tests/Cases/KebabCaseExtensionsTests.cs
new file mode 100644
index 0000000..a56d6d4
--- /dev/null
+++ b/TJC.StringExtensions.Tests/Cases/KebabCaseExtensionsTests.cs
@@ -0,0 +1,21 @@
+using TJC.StringExtensions.Cases;
+
+namespace TJC.StringExtensions.Tests.Cases;
+
+[TestClass]
+public class KebabCaseExtensionsTests
+{
+ [TestMethod]
+ public void ToKebabCaseTest()
+ {
+ // Arrange
+ var input = "Kebab Case Extensions";
+ var expected = "kebab-case-extensions";
+
+ // Act
+ var result = input.ToKebabCase();
+
+ // Assert
+ Assert.AreEqual(expected, result);
+ }
+}
\ No newline at end of file
diff --git a/TJC.StringExtensions.Tests/Cases/PascalCaseExtensionsTests.cs b/TJC.StringExtensions.Tests/Cases/PascalCaseExtensionsTests.cs
new file mode 100644
index 0000000..51f8e1d
--- /dev/null
+++ b/TJC.StringExtensions.Tests/Cases/PascalCaseExtensionsTests.cs
@@ -0,0 +1,21 @@
+using TJC.StringExtensions.Cases;
+
+namespace TJC.StringExtensions.Tests.Cases;
+
+[TestClass]
+public class PascalCaseExtensionsTests
+{
+ [TestMethod]
+ public void ToPascalCaseTest()
+ {
+ // Arrange
+ var input = "Pascal Case Extensions";
+ var expected = "PascalCaseExtensions";
+
+ // Act
+ var result = input.ToPascalCase();
+
+ // Assert
+ Assert.AreEqual(expected, result);
+ }
+}
\ No newline at end of file
diff --git a/TJC.StringExtensions.Tests/Cases/SnakeCaseExtensionsTests.cs b/TJC.StringExtensions.Tests/Cases/SnakeCaseExtensionsTests.cs
new file mode 100644
index 0000000..3d2da30
--- /dev/null
+++ b/TJC.StringExtensions.Tests/Cases/SnakeCaseExtensionsTests.cs
@@ -0,0 +1,21 @@
+using TJC.StringExtensions.Cases;
+
+namespace TJC.StringExtensions.Tests.Cases;
+
+[TestClass]
+public class SnakeCaseExtensionsTests
+{
+ [TestMethod]
+ public void ToSnakeCaseTest()
+ {
+ // Arrange
+ var input = "Snake Case Extensions";
+ var expected = "snake_case_extensions";
+
+ // Act
+ var result = input.ToSnakeCase();
+
+ // Assert
+ Assert.AreEqual(expected, result);
+ }
+}
\ No newline at end of file
diff --git a/TJC.StringExtensions.Tests/Cases/TrainCaseExtensionsTests.cs b/TJC.StringExtensions.Tests/Cases/TrainCaseExtensionsTests.cs
new file mode 100644
index 0000000..56efb80
--- /dev/null
+++ b/TJC.StringExtensions.Tests/Cases/TrainCaseExtensionsTests.cs
@@ -0,0 +1,21 @@
+using TJC.StringExtensions.Cases;
+
+namespace TJC.StringExtensions.Tests.Cases;
+
+[TestClass]
+public class TrainCaseExtensionsTests
+{
+ [TestMethod]
+ public void ToTrainCaseTest()
+ {
+ // Arrange
+ var input = "Train Case Extensions";
+ var expected = "Train-Case-Extensions";
+
+ // Act
+ var result = input.ToTrainCase();
+
+ // Assert
+ Assert.AreEqual(expected, result);
+ }
+}
\ No newline at end of file
diff --git a/TJC.StringExtensions/Cases/CamelCaseExtensions.cs b/TJC.StringExtensions/Cases/CamelCaseExtensions.cs
index 0f9690a..3373f72 100644
--- a/TJC.StringExtensions/Cases/CamelCaseExtensions.cs
+++ b/TJC.StringExtensions/Cases/CamelCaseExtensions.cs
@@ -9,16 +9,28 @@ public static class CamelCaseExtensions
{
///
/// Split camel case with a separator (typically a space).
- ///
- /// Example: "camelCaseExtensions" becomes "camel Case Extensions"
///
///
///
- ///
+ /// "camelCaseExtensions" becomes "camel Case Extensions"
public static string SplitCamelCase(this string? input, string separator = " ")
{
if (string.IsNullOrEmpty(input))
return string.Empty;
return string.Concat(input.Select((x, i) => i > 0 && char.IsUpper(x) ? $"{separator}{x}" : x.ToString()));
}
+
+ ///
+ /// Convert any case format to camel case.
+ ///
+ ///
+ /// camelCase
+ public static string ToCamelCase(this string input)
+ {
+ var words = input.CodeCaseToWords();
+ var result = new StringBuilder(words[0].ToLower());
+ for (int i = 1; i < words.Length; i++)
+ result.Append(char.ToUpper(words[i][0]) + words[i][1..].ToLower());
+ return result.ToString();
+ }
}
\ No newline at end of file
diff --git a/TJC.StringExtensions/Cases/CodeCaseExtensions.cs b/TJC.StringExtensions/Cases/CodeCaseExtensions.cs
new file mode 100644
index 0000000..92d4590
--- /dev/null
+++ b/TJC.StringExtensions/Cases/CodeCaseExtensions.cs
@@ -0,0 +1,41 @@
+namespace TJC.StringExtensions.Cases;
+
+///
+/// Case extensions for strings.
+///
+public static partial class CodeCaseExtensions
+{
+ private static readonly char[] _separator = [' ', '_', '-'];
+
+ ///
+ /// Splits any code case format with a separator.
+ ///
+ ///
+ ///
+ ///
+ public static string SplitCodeCase(this string input, string separator = " ")
+ {
+ if (string.IsNullOrEmpty(input))
+ return string.Empty;
+ return string.Join(separator, input.CodeCaseToWords());
+ }
+
+ ///
+ /// Convert any code case format to words array.
+ ///
+ ///
+ ///
+ public static string[] CodeCaseToWords(this string input)
+ {
+ if (string.IsNullOrWhiteSpace(input))
+ return [];
+ // Add spaces around transitions (camelCase, PascalCase) and split by space, hyphen, or underscore
+ var spaced = CaseWordSplitter.Replace(input, " ");
+ return spaced.Split(_separator, StringSplitOptions.RemoveEmptyEntries);
+ }
+
+ private static readonly Regex CaseWordSplitter = CaseWordSplitterRegex();
+
+ [GeneratedRegex(@"[a-z][A-Z]|[_\- ]", RegexOptions.Compiled)]
+ private static partial Regex CaseWordSplitterRegex();
+}
\ No newline at end of file
diff --git a/TJC.StringExtensions/Cases/KebabCaseExtensions.cs b/TJC.StringExtensions/Cases/KebabCaseExtensions.cs
new file mode 100644
index 0000000..5b087a1
--- /dev/null
+++ b/TJC.StringExtensions/Cases/KebabCaseExtensions.cs
@@ -0,0 +1,17 @@
+namespace TJC.StringExtensions.Cases;
+
+///
+/// Kebab case extensions for strings.
+///
+/// Example of kebab case: "kebab-case-extensions"
+///
+public static class KebabCaseExtensions
+{
+ ///
+ /// Convert any case format to kebab case.
+ ///
+ ///
+ /// kebab-case
+ public static string ToKebabCase(this string input) =>
+ string.Join("-", input.CodeCaseToWords()).ToLower();
+}
\ No newline at end of file
diff --git a/TJC.StringExtensions/Cases/PascalCaseExtensions.cs b/TJC.StringExtensions/Cases/PascalCaseExtensions.cs
new file mode 100644
index 0000000..462a3fd
--- /dev/null
+++ b/TJC.StringExtensions/Cases/PascalCaseExtensions.cs
@@ -0,0 +1,23 @@
+namespace TJC.StringExtensions.Cases;
+
+///
+/// Pascal case extensions for strings.
+///
+/// Example of pascal case: "PascalCaseExtensions"
+///
+public static class PascalCaseExtensions
+{
+ ///
+ /// Convert any case format to pascal case.
+ ///
+ ///
+ /// PascalCase
+ public static string ToPascalCase(this string input)
+ {
+ var words = input.CodeCaseToWords();
+ var result = new StringBuilder();
+ foreach (var word in words)
+ result.Append(char.ToUpper(word[0]) + word[1..].ToLower());
+ return result.ToString();
+ }
+}
\ No newline at end of file
diff --git a/TJC.StringExtensions/Cases/SnakeCaseExtensions.cs b/TJC.StringExtensions/Cases/SnakeCaseExtensions.cs
new file mode 100644
index 0000000..0765f85
--- /dev/null
+++ b/TJC.StringExtensions/Cases/SnakeCaseExtensions.cs
@@ -0,0 +1,17 @@
+namespace TJC.StringExtensions.Cases;
+
+///
+/// Snake case extensions for strings.
+///
+/// Example of snake case: "snake-case-extensions"
+///
+public static class SnakeCaseExtensions
+{
+ ///
+ /// Convert any case format to snake case.
+ ///
+ ///
+ /// snake_case
+ public static string ToSnakeCase(this string input) =>
+ string.Join("_", input.CodeCaseToWords()).ToLower();
+}
\ No newline at end of file
diff --git a/TJC.StringExtensions/Cases/TrainCaseExtensions.cs b/TJC.StringExtensions/Cases/TrainCaseExtensions.cs
new file mode 100644
index 0000000..c2f8b4c
--- /dev/null
+++ b/TJC.StringExtensions/Cases/TrainCaseExtensions.cs
@@ -0,0 +1,18 @@
+namespace TJC.StringExtensions.Cases;
+
+///
+/// Train case extensions for strings.
+///
+/// Example of train case: "Train-Case-Extensions"
+///
+public static class TrainCaseExtensions
+{
+ ///
+ /// Convert any case format to train case.
+ ///
+ ///
+ /// Train-Case
+ public static string ToTrainCase(this string input) =>
+ string.Join("-", input.CodeCaseToWords()
+ .Select(word => char.ToUpper(word[0]) + word[1..].ToLower()));
+}
\ No newline at end of file
diff --git a/TJC.StringExtensions/GlobalUsings.cs b/TJC.StringExtensions/GlobalUsings.cs
index d1ccefb..2882fc1 100644
--- a/TJC.StringExtensions/GlobalUsings.cs
+++ b/TJC.StringExtensions/GlobalUsings.cs
@@ -1 +1,3 @@
-global using TJC.StringExtensions.Separator;
\ No newline at end of file
+global using System.Text;
+global using System.Text.RegularExpressions;
+global using TJC.StringExtensions.Separator;
\ No newline at end of file