From af8b040d332d2d27b89e9c31799c2de0179abfa4 Mon Sep 17 00:00:00 2001 From: Nasir Zubair Date: Tue, 21 Oct 2014 22:08:59 -0400 Subject: [PATCH 1/7] added test to find dash/hyphen with preceeding or following spaces or both --- src/Humanizer/StringHumanizeExtensions.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Humanizer/StringHumanizeExtensions.cs b/src/Humanizer/StringHumanizeExtensions.cs index ed597604c..b8fc6abb1 100644 --- a/src/Humanizer/StringHumanizeExtensions.cs +++ b/src/Humanizer/StringHumanizeExtensions.cs @@ -51,6 +51,12 @@ public static string Humanize(this string input) if (input.ToCharArray().All(Char.IsUpper)) return input; + // if input contains a dash or hyphen which preceeds or follows a space (or both, i.g. free-standing) + // remove the dash/hyphen and run it through FromPascalCase + Regex r = new Regex(@"[\s]{1}[-_][\s]{0}|[\s]{0}[-_][\s]{1}", RegexOptions.IgnoreCase); + if (r.IsMatch(input)) + return FromPascalCase(FromUnderscoreDashSeparatedWords(input)); + if (input.Contains("_") || input.Contains("-")) return FromUnderscoreDashSeparatedWords(input); From 19d9a0902424a0a9b08e97a38e56145f0227fa85 Mon Sep 17 00:00:00 2001 From: Nasir Zubair Date: Tue, 21 Oct 2014 22:14:41 -0400 Subject: [PATCH 2/7] updated regex to account for words/acronyms/numbers separated by spaces. The regex can be refined to exclude leading and trailing spaces from the results of pascalCaseWordBoundary.Split(). For now, word.Trim() is added to discard the unneeded space. --- src/Humanizer/StringHumanizeExtensions.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Humanizer/StringHumanizeExtensions.cs b/src/Humanizer/StringHumanizeExtensions.cs index b8fc6abb1..23f050f89 100644 --- a/src/Humanizer/StringHumanizeExtensions.cs +++ b/src/Humanizer/StringHumanizeExtensions.cs @@ -24,15 +24,17 @@ static string FromPascalCase(string input) (?# acronym to number) (?<=[A-Z])(?=[0-9])| (?# acronym to word) -(?<=[A-Z])(?=[A-Z][a-z]) +(?<=[A-Z])(?=[A-Z][a-z])| +(?# words/acronyms/numbers separated by space) +(?<=[^\s])(?=[\s]) ", RegexOptions.IgnorePatternWhitespace); var result = pascalCaseWordBoundaryRegex .Split(input) .Select(word => - word.ToCharArray().All(Char.IsUpper) && word.Length > 1 - ? word - : word.ToLower()) + word.Trim().ToCharArray().All(Char.IsUpper) && word.Trim().Length > 1 + ? word.Trim() + : word.Trim().ToLower()) .Aggregate((res, word) => res + " " + word); result = Char.ToUpper(result[0]) + From 42d6ad7adc8aa0fcbdb9b2afd77ef05ceeaac3de Mon Sep 17 00:00:00 2001 From: Nasir Zubair Date: Tue, 21 Oct 2014 22:21:08 -0400 Subject: [PATCH 3/7] added various test cases for space, dash and hyphen handling. --- src/Humanizer.Tests/StringHumanizeTests.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Humanizer.Tests/StringHumanizeTests.cs b/src/Humanizer.Tests/StringHumanizeTests.cs index 0af0ca213..800decee7 100644 --- a/src/Humanizer.Tests/StringHumanizeTests.cs +++ b/src/Humanizer.Tests/StringHumanizeTests.cs @@ -11,6 +11,7 @@ public class StringHumanizeTests [InlineData("10IsInTheBegining", "10 is in the begining")] [InlineData("NumberIsAtTheEnd100", "Number is at the end 100")] [InlineData("XIsFirstWordInTheSentence", "X is first word in the sentence")] + [InlineData("XIsFirstWordInTheSentence ThenThereIsASpace", "X is first word in the sentence then there is a space")] public void CanHumanizeStringInPascalCase(string input, string expectedResult) { Assert.Equal(expectedResult, input.Humanize()); @@ -19,6 +20,14 @@ public void CanHumanizeStringInPascalCase(string input, string expectedResult) [Theory] [InlineData("Underscored_input_string_is_turned_into_sentence", "Underscored input string is turned into sentence")] [InlineData("Underscored_input_String_is_turned_INTO_sentence", "Underscored input String is turned INTO sentence")] + [InlineData("TEST 1 - THIS IS A TEST", "TEST 1 THIS IS A TEST")] + [InlineData("TEST 1 -THIS IS A TEST", "TEST 1 THIS IS A TEST")] + [InlineData("TEST 1- THIS IS A TEST", "TEST 1 THIS IS A TEST")] + [InlineData("TEST 1_ THIS IS A TEST", "TEST 1 THIS IS A TEST")] + [InlineData("TEST 1 _THIS IS A TEST", "TEST 1 THIS IS A TEST")] + [InlineData("TEST 1 _ THIS IS A TEST", "TEST 1 THIS IS A TEST")] + [InlineData("TEST 1 - THIS_IS_A_TEST", "TEST 1 THIS IS A TEST")] + [InlineData("TEST 1 - THIS is A Test", "TEST 1 THIS is A test")] public void CanHumanizeStringWithUnderscores(string input, string expectedReseult) { Assert.Equal(expectedReseult, input.Humanize()); @@ -28,6 +37,7 @@ public void CanHumanizeStringWithUnderscores(string input, string expectedReseul [InlineData("HTML", "HTML")] [InlineData("TheHTMLLanguage", "The HTML language")] [InlineData("HTMLIsTheLanguage", "HTML is the language")] + [InlineData("TheLanguage IsHTML", "The language is HTML")] [InlineData("TheLanguageIsHTML", "The language is HTML")] [InlineData("HTML5", "HTML 5")] [InlineData("1HTML", "1 HTML")] From 6469e2d5129f438e11bd1cb77998119c28977f7d Mon Sep 17 00:00:00 2001 From: Nasir Zubair Date: Tue, 21 Oct 2014 22:29:07 -0400 Subject: [PATCH 4/7] Removed unneccessary .Trim() from word.Length line --- src/Humanizer/StringHumanizeExtensions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Humanizer/StringHumanizeExtensions.cs b/src/Humanizer/StringHumanizeExtensions.cs index 23f050f89..c3a5774d6 100644 --- a/src/Humanizer/StringHumanizeExtensions.cs +++ b/src/Humanizer/StringHumanizeExtensions.cs @@ -32,7 +32,7 @@ static string FromPascalCase(string input) var result = pascalCaseWordBoundaryRegex .Split(input) .Select(word => - word.Trim().ToCharArray().All(Char.IsUpper) && word.Trim().Length > 1 + word.Trim().ToCharArray().All(Char.IsUpper) && word.Length > 1 ? word.Trim() : word.Trim().ToLower()) .Aggregate((res, word) => res + " " + word); From e1f1d8a97244a90d8b0d458092d5afd441d0819c Mon Sep 17 00:00:00 2001 From: Nasir Zubair Date: Wed, 22 Oct 2014 20:09:23 -0400 Subject: [PATCH 5/7] Removed multiple Trim()s within Select(), added a single Trim() in Aggregate() --- src/Humanizer/StringHumanizeExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Humanizer/StringHumanizeExtensions.cs b/src/Humanizer/StringHumanizeExtensions.cs index c3a5774d6..2f5a7ec2e 100644 --- a/src/Humanizer/StringHumanizeExtensions.cs +++ b/src/Humanizer/StringHumanizeExtensions.cs @@ -33,9 +33,9 @@ static string FromPascalCase(string input) .Split(input) .Select(word => word.Trim().ToCharArray().All(Char.IsUpper) && word.Length > 1 - ? word.Trim() - : word.Trim().ToLower()) - .Aggregate((res, word) => res + " " + word); + ? word + : word.ToLower()) + .Aggregate((res, word) => res + " " + word.Trim()); result = Char.ToUpper(result[0]) + result.Substring(1, result.Length - 1); From ca6e447f6c0711b063bbc6637efb757ebd98e5f8 Mon Sep 17 00:00:00 2001 From: Nasir Zubair Date: Wed, 22 Oct 2014 20:13:11 -0400 Subject: [PATCH 6/7] Simplified regex by removing [\s]{0}. Updated comment to say 'underscore' instead of 'hyphen' --- src/Humanizer/StringHumanizeExtensions.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Humanizer/StringHumanizeExtensions.cs b/src/Humanizer/StringHumanizeExtensions.cs index 2f5a7ec2e..cf60c2e58 100644 --- a/src/Humanizer/StringHumanizeExtensions.cs +++ b/src/Humanizer/StringHumanizeExtensions.cs @@ -53,9 +53,9 @@ public static string Humanize(this string input) if (input.ToCharArray().All(Char.IsUpper)) return input; - // if input contains a dash or hyphen which preceeds or follows a space (or both, i.g. free-standing) - // remove the dash/hyphen and run it through FromPascalCase - Regex r = new Regex(@"[\s]{1}[-_][\s]{0}|[\s]{0}[-_][\s]{1}", RegexOptions.IgnoreCase); + // if input contains a dash or underscore which preceeds or follows a space (or both, i.g. free-standing) + // remove the dash/underscore and run it through FromPascalCase + Regex r = new Regex(@"[\s]{1}[-_]|[-_][\s]{1}", RegexOptions.IgnoreCase); if (r.IsMatch(input)) return FromPascalCase(FromUnderscoreDashSeparatedWords(input)); From 0e6edfecf341efe885c277b404e0916496c25a91 Mon Sep 17 00:00:00 2001 From: Nasir Zubair Date: Wed, 22 Oct 2014 20:22:27 -0400 Subject: [PATCH 7/7] Updated release_notes.md with PR#341 information. --- release_notes.md | 1 + 1 file changed, 1 insertion(+) diff --git a/release_notes.md b/release_notes.md index bdb42f1ae..1853f41ef 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,4 +1,5 @@ ###In Development + - [#341](https://github.com/MehdiK/Humanizer/pull/341): Added logic to properly treat underscores, dashes and spaces. [Commits](https://github.com/MehdiK/Humanizer/compare/v1.29.0...master)