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


1 不跟你多廢話 上代碼!

    /// <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 使用效果

  

5 后記

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

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

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

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

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

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

  在公司的年會上

  我終於想到了,看着我身旁的妹子們(我同事),誒亞,好激動。

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

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM