我从 mellamokb 的解决方案中大量借鉴了一些更全面的东西。例如,我想留下数字。此外,我希望将任何非字母、非数字字符用作分隔符。这里是:
public static string ToPascalCase(this string s) {
var result = new StringBuilder();
var nonWordChars = new Regex(@"[^a-zA-Z0-9]+");
var tokens = nonWordChars.Split(s);
foreach (var token in tokens) {
result.Append(PascalCaseSingleWord(token));
}
return result.ToString();
}
static string PascalCaseSingleWord(string s) {
var match = Regex.Match(s, @"^(?<word>\d+|^[a-z]+|[A-Z]+|[A-Z][a-z]+|\d[a-z]+)+$");
var groups = match.Groups["word"];
var textInfo = Thread.CurrentThread.CurrentCulture.TextInfo;
var result = new StringBuilder();
foreach (var capture in groups.Captures.Cast<Capture>()) {
result.Append(textInfo.ToTitleCase(capture.Value.ToLower()));
}
return result.ToString();
}
这是一个 x 单元测试,显示了一些测试用例:
[Theory]
[InlineData("imAString", "ImAString")]
[InlineData("imAlsoString", "ImAlsoString")]
[InlineData("ImAlsoString", "ImAlsoString")]
[InlineData("im_a_string", "ImAString")]
[InlineData("im a string", "ImAString")]
[InlineData("ABCAcronym", "AbcAcronym")]
[InlineData("im_a_ABCAcronym", "ImAAbcAcronym")]
[InlineData("im a ABCAcronym", "ImAAbcAcronym")]
[InlineData("8ball", "8Ball")]
[InlineData("im a 8ball", "ImA8Ball")]
[InlineData("IM_ALL_CAPS", "ImAllCaps")]
[InlineData("IM ALSO ALL CAPS", "ImAlsoAllCaps")]
[InlineData("i-have-dashes", "IHaveDashes")]
[InlineData("a8word_another_word", "A8WordAnotherWord")]
public void WhenGivenString_ShouldPascalCaseIt(string input, string expectedResult) {
var result = input.ToPascalCase();
Assert.Equal(expectedResult, result);
}