将属性名称转换为有效的json字段标识符

时间:2018-06-11 04:17:21

标签: c# json

我正在努力编写一个方便的小扩展方法,它将获取一个字符串并将其格式化,就好像它是一个lowerCamelCase JSON标识符一样。

这就是我到目前为止......请帮助我改进它吗?

我需要以下行为:

  • UserName =>的userName
  • UserID =>用户id
  • user =>用户
  • 钓鱼之旅=> fishingTrip
  • 123123123 => 123123123
  • aaa123 => AAA123
  • 你好世界这是我=> helloWorldThisIsMe

奖金 - 如果我们能以某种方式去除非[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

1 个答案:

答案 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();
}