我正在努力编写一个方便的小扩展方法,它将获取一个字符串并将其格式化,就好像它是一个lowerCamelCase JSON标识符一样。
这就是我到目前为止......请帮助我改进它吗?
我需要以下行为:
奖金 - 如果我们能以某种方式去除非[A-Za-z0-9]字符?我想我可以做另一轮正则表达式?
感谢您的帮助!
public static string ToJsonIdentifier(string s)
{
// special case, s is empty
if (string.IsNullOrEmpty(s)) return s;
// clean up the string, remove any non-standard chars
s = Regex.Replace(s, @"[^A-Za-z0-9\s]+", "");
// special case s is whitespace
if (string.IsNullOrWhiteSpace(s)) return String.Empty;
// special case s is only 1 letter
if (!string.IsNullOrEmpty(s) && s.Length == 1)
return s.ToLowerInvariant();
// detect word boundaries where the case changes and add whitespace there, so the next code splits it up
s = Regex.Replace(s, "([a-z])([A-Z])", m=> m.Groups[1].Value + " " + m.Groups[2].Value);
// multiple words, so for each whitespace separated bit, uppercase the first letter, and deal with special cases
if (s.Contains(" "))
{
s = string.Join("", s.Split(' ').ToList().Select(z =>
{
if (string.IsNullOrWhiteSpace(z)) return string.Empty;
if (z.Length == 1) return z.ToUpperInvariant();
return z.ToUpperInvariant()
.Substring(0, 1) + z.Substring(1).ToLowerInvariant();
}));
}
// lowercase the first letter
return char.ToLower(s[0]) + s.Substring(1);
}
研究:我看过这些看似相关的问题:
我正在进行的尝试:https://dotnetfiddle.net/PR31Hl
答案 0 :(得分:1)
您的代码似乎已经给出了预期的结果。你想改进什么部分?
我认为这不是你需要的答案。但我只想分享一下如何解决这个问题,我不会使用Linq / Regex,而只需检查字符串中的每个字符的内存(而不是Linq / Regex库)效率。我想这也应该在这个过程中更轻量级。但要注意,这可能不容易阅读。
public static string ToJsonIdentifier(string s)
{
// special case, s is empty
if (string.IsNullOrEmpty(s)) return s;
var result = new StringBuilder();
bool isFirst = true; // Is First (non-whitespace) Character Flag
bool isSpace = false; // Is Whitespace Flag
bool isUpperCase = false; // Is Uppercase Flag
foreach(char c in s)
{
// filter to be letter or digit only
if(!char.IsLetterOrDigit(c))
{
continue;
}
if(isFirst)
{
if (!char.IsWhiteSpace(c))
{
// if first character, set to lower case
result.Append(char.ToLower(c));
isFirst = false; // no more first flag
}
// if WhiteSpace, ignore the character
}
else if(char.IsWhiteSpace(c))
{
isSpace = true; // set the Whitespace flag, so next char should be uppercase
}
else if(char.IsUpper(c))
{
if (!isUpperCase)
{
// if previous char is lower case, set it as it is (as uppercase)
result.Append(c);
isUpperCase = true;
}
else
{
// if previous char is uppercase, set this to lower instead
result.Append(char.ToLower(c));
// and keep the uppercase flag on, so multiple uppercase in the row will be converted to lower, until lower case is found.
}
}
else if(char.IsLower(c))
{
if(isSpace) // if previous char is whitespace, set char to be upper case
{
isSpace = false; // no more whitespace flag
result.Append(char.ToUpper(c));
isUpperCase = true; // set upper case flag on
}
else
{
isUpperCase = false; // no more upper case flag
result.Append(c);
}
}
else if(char.IsDigit(c))
{
// reset all flags
isSpace = false;
isUpperCase = false;
result.Append(c);
}
}
return result.ToString();
}