天天看點

SQL關鍵字轉換大寫核心算法實作

1 不跟你多廢話 上代碼!

SQL關鍵字轉換大寫核心算法實作
SQL關鍵字轉換大寫核心算法實作

/// <summary>
    /// SQL關鍵字轉換器
    /// </summary>
    public class SqlConverter : IKeywordsConvertible
    {
        public SqlConverter(string[] keywords)
        {
            Keywords = keywords;
        }
        public SqlConverter() { }

        /// <summary>
        /// 關鍵字集合
        /// </summary>
        public string[] Keywords
        {
            get { return keywords; }
            set
            {
                this.keywords = new string[value.Length];
                for (int i = 0; i < value.Length; i++)
                {
                    this.keywords[i] = value[i].ToLower();
                }
            }
        }

        private string[] keywords;

        /// <summary>
        /// 字元緩沖區
        /// </summary>
        private StringBuilder charBuilder = new StringBuilder();

        /// <summary>
        /// 符号緩沖區
        /// </summary>
        private StringBuilder symboBuilder = new StringBuilder();

        /// <summary>
        /// 結果緩沖區
        /// </summary>
        private StringBuilder resBuilder = new StringBuilder();

        /// <summary>
        /// 上一個字元是否是字母
        /// </summary>
        private bool lastIsLetter;

        /// <summary>
        /// 臨時變量
        /// </summary>
        private string temp;

        /// <summary>
        /// 轉換
        /// </summary>
        /// <param name="source">要轉換的字元串</param>
        /// <returns>轉換結果</returns>
        public string Convert(string source)
        {
            charBuilder.Clear();
            symboBuilder.Clear();
            resBuilder.Clear();
            lastIsLetter = true;
            temp = string.Empty;

            // 打散源字元串
            char[] charArray = source.ToArray<char>();

            // 周遊
            foreach (var c in charArray)
            {
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
                {
                    // 如果上一個符号不是字母,就把符号緩沖區推送
                    if (!lastIsLetter)
                    {
                        PushSymbols();
                    }
                    charBuilder.Append(c);
                    lastIsLetter = true;
                }
                else
                {
                    // 如果上一個符号是字母,就把字母緩沖區推送
                    if (lastIsLetter)
                    {
                        PushLetters();
                    }
                    symboBuilder.Append(c);
                    lastIsLetter = false;
                }
            }

            // 處理最後一個緩沖區
            if (lastIsLetter)
            {
                PushLetters();
            }
            else
            {
                PushSymbols();
            }

            return resBuilder.ToString();
        }

        /// <summary>
        /// 将字元緩沖區推送至目标緩沖區
        /// </summary>
        private void PushLetters()
        {
            temp = charBuilder.ToString();
            if (Keywords.Contains(temp.ToLower()))
            {
                resBuilder.Append(temp.ToUpper());
            }
            else
            {
                resBuilder.Append(temp);
            }
            charBuilder.Clear();
        }

        /// <summary>
        /// 将符号緩沖區推送至目标緩沖區
        /// </summary>
        private void PushSymbols()
        {
            resBuilder.Append(symboBuilder.ToString());
            symboBuilder.Clear();
        }
    }      

View Code

2 原理

  第一步 :将一個SQL語句字元串拆開來,拆成 字元串-符号串-字元串-符号串-符号串-字元串 這樣

  第二步 :然後判斷字元串是不是關鍵字,是的話就轉成大寫

  第三部 :再将這些串拼起來

3 實作

  原理看似很簡單,但實作卻不簡單。

  要處理兩個問題

    1 不可能全轉換之後再處理拼接,是以必須邊拼接邊轉換

    2 狀态切換,什麼時候推送

  實作步驟

    1 源串打碎成char數組

    2 拼接 重點是判斷 如何确定 字母和符号狀态,以及在狀态切換至将緩沖區推送。詳情看代碼

    3 最後要再做一次,因為周遊之後最後一個串沒有機會被推送

4 使用效果

  

SQL關鍵字轉換大寫核心算法實作

5 後記

  最近公司修改了SQL規範,要求SQL關鍵字大寫,诶,我寫了那麼多沒上線,都要改。作為一個程式員,這肯定是可以用代碼來幹的啊。

  于是,我動手百度!對我沒有自己寫,我懶。

  百到了一個工具,為了安全起見,我反編譯了工具,看了看代碼。沒危險。但是啊,看不懂,功能倒是實作了。

  于是我就先用着把我的SQL都改了。

  但是我覺得,我看不懂啊,沒學到。我想自己去實作!

  于是随後的幾天我開始思索如何來将SQL關鍵字變大寫,又不會影響其他的部分,包括回車換行這些不可見符号(就是不能用不可見符号做分割,因為如果有相連的不可符号,切割之後會丢失)。

  在公司的年會上

  我終于想到了,看着我身旁的妹子們(我同僚),诶亞,好激動。

  利用閑暇時間,寫了這個,獨立的思考沒有參考我找的的工具的代碼。

  核心算法發出來,一起學習與交流。