在C#中實現Python的分片技術


在C#中實現Python的分片技術

前言

  之前在學習Python的時候發現Python中的分片技術超好玩的,本人也是正則表達式熱愛狂,平時用C#比較多,所以決定把Python中的分片技術在C#中實現,添加到個人類庫中,以便日后在寫C#代碼的時候能舔一舔Python的味道。

效果展示

             Python版:           C#版:

 

切割技術講解

  這里先簡要講解一下Python中的分片技術,其他Python前輩也對此技術有豐富多彩的講解文章,這里只是簡要說明一下,好讓讀者們能知道下怎么回事,如果想更深入了解Python的分片技術,這里並不適合你哦。

  分片的對象可以是字符串或者序列,本文提供字符串的實現方法,其實序列差不多的,我也會在最后提供字符串和序列的實現代碼,並且附帶單元測試。

  好了,廢話不多說,其實看了上面的Python版的結果,我想聰明的您就略知一二了。分片的模板是:變量[起始位置:終點位置:步長],舉個例子:a="abcdfeghij",那么a[0:2:1]這個的結果就是零位置開始(a的左邊),步長為1(也就是連續取),到2位置結束(從a的左邊開始:0->(a的左邊),1->(b的左邊,a的右邊),2->(c的左邊,b的右邊)->結束),好了,結果就是"ab"。

       注意事項:1.步長可以忽略不寫(默認為1),如果步長為2,就每取一個跳過1個,以此類推。

            2.可以使用負數a[-3:-1:1],結果是"ef",讀者們可以自己推一下,很簡單。

            3.分片技術可以針對字符串,也可以針對序列。

  

實現過程

  這里需要用到正則表達式的技術,可能對一些朋友來說比較難懂,但是我會盡量講解的簡單一點。

  首先,要使用分片,有三個參數可以控制:起始位置,結束位置,步長。所以在正則表達式應該嵌入這三個參數變量,在匹配的時候動態生成正則表達式。下面來看需要把這三個參數放到哪里:

    起始位置:

        1.背景

            這里使用肯定逆序環視,什么是肯定逆序環視,就是匹配到的位置那一點向后看,向后看的內容必須符合環視的內容,舉個例子:文本:abc  ,正則表達式:(?<=a)b,肯定逆序環視符號:(?<=exp),這個正則表達式的意思就是找到b,然后向后看(左邊),如果a就匹配成功,結果就是b(因為逆序環視是不納入結果中)。

          2.實現

            我使用[\s\S]來表示一個任意符號,含有位置參數的部分放到左邊,形成這樣一個正則表達式:

(?<=^[\s\S]{StarIndex,})[\s\S]  注意這里的StarIndex是變量,可以是0,1,2,3..!以StarIndex=2(其實位置是2)為例,匹配一個任意字

符,並且向后看(左邊)是開頭->2個或者多個任意字符。

    結束位置:

         1.背景

            這里使用肯定順序環視,什么是肯定順序環視,就是匹配到的位置那一點向前看,向前看的內容必須符合環視的內容,舉個例子:文本abc ,正則表達式:(?=b)a,肯定逆序環視符號:(?=exp),這個正則表達式的意思就是找到a,然后向前看(右邊),如果是b就匹配成功,結果就是a(因為順序環視是不納入結果中)。

         2.實現

            有了前面表達式基礎,我需要在后面添加一個順序環視,形成這樣一個表達式(合並過后):

(?<=^[\s\S]{StarIndex,})[\s\S](?=[\s\S]{EndCount}),這里要注意了,EndCount並不是結束位置,計算公式:

EndCount=String.Length-EndIndex。字符串長度-結束位置。

    步長:

       最后終於到步長了,這是關鍵的一步,用於連接上面兩部的,其實基礎前面已經講了,下面給出加入步長邏輯以后,形成的最后正則表達式:(?<=^[\s\S]{StarIndex,})(?<=^[\s\S]{MiddleCount})[\s\S](?=[\s\S]{EndCount}),步長參數為Step變量,這里的MiddleCount在循環中改變,每次循環都MiddleCount=MiddleCount+Step;循環到最后合並獲取到的字符形成結果字符串!!。

 

實例演示

    最后演示一下具體匹配實例,過程,結果。

    字符串:a="abcdefghij";  a.Cut(0,3,1);

        循環次數:3-0=3次。

循環一:表達式:(?<=^[\s\S]{0,})(?<=^[\s\S]{0})[\s\S](?=[\s\S]{7})

      結果圖:  =====》'a'

 

循環二:表達式(?<=^[\s\S]{0,})(?<=^[\s\S]{1})[\s\S](?=[\s\S]{7})

     結果圖:=====》'b'

 

循環三:表達式(?<=^[\s\S]{0,})(?<=^[\s\S]{2})[\s\S](?=[\s\S]{7})

     結果圖:=====》'c' 

 

    最終合並結果:"abc"。最后貼一張Python中的結果:.

 

代碼展示

  

public static class StringExpander
    {
        /// <summary>
        /// Python中的字符串切片技術,[開始索引:結束索引:步長值]
        /// </summary>
        /// <param name="Str">目標字符串</param>
        /// <param name="StarIndex">開始索引</param>
        /// <param name="EndIndex">結束索引</param>
        /// <param name="Step">步長值</param>
        /// <returns></returns>
        public static String StringCut(this String Str, Int32 StarIndex, Int32 EndIndex, Int32 Step = 1)
        {
            if (EndIndex < 0)
            { EndIndex = Str.Length + EndIndex; }
            if (StarIndex < 0)
            { StarIndex = Str.Length + StarIndex; }
            StringBuilder sb = new StringBuilder();
            Int32 LoopTime = EndIndex - StarIndex;
            if (EndIndex > Str.Length) { EndIndex = Str.Length; }
            Int32 EndCount = Str.Length - EndIndex;
            int j = StarIndex;
            for (int i = 0; i < LoopTime; i = i + Step)
            {
                String RegexString = @"(?<=^[\s\S]{" + StarIndex + @",})(?<=^[\s\S]{" + j + @"})[\s\S](?=[\s\S]{" + EndCount + @"})";
                try
                {
                    sb.Append(Regex.Match(Str, RegexString).Value);
                }
                catch { }
                j = j + Step;
            }
            return sb.ToString();
        }
        /// <summary>
        /// Python中的字符串切片技術,只提供位置
        /// </summary>
        /// <param name="Str">目標字符串</param>
        /// <param name="StarIndex">位置</param>
        /// <returns></returns>
        public static String StringCut(this String Str, Int32 StarIndex)
        {
            if (StarIndex < 0)
            { StarIndex = Str.Length + StarIndex; }
            return Str.Substring(StarIndex, 1);
        }
    }

 

總結

  現在提供的是字符串的實現方法,在下面可以下載Demo,里面有序列的實現方法,思想差不多,但是需要添加點東西。謝謝大家觀看!

  

                源碼下載


免責聲明!

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



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