Python Regex進階應用程式舉例

來源:互聯網
上載者:User
    首先,寫這篇文章的起因,是這兩天玩了一個網站    http://www.checkio.org    用Python做題、出題,交流,很有意思也很有挑戰。
————————————進入正題——————————————————————————
    其中一道字串處理的題目如下:http://www.checkio.org/mission/implementation/1088/python-27/    簡單來說,輸入是一個字串,輸出也是一個字串。我們要做的,是讓輸入中的整數每隔三位元加一個小數點。
測試案例:    assert checkio('123456') == '123.456'    assert checkio('333') == '333'    assert checkio('9999999') == '9.999.999'    assert checkio('123456 567890') == '123.456 567.890'    assert checkio('price is 5799') == 'price is 5.799'    assert checkio('he was born in 1966th') == 'he was born in 1966th'
    題意應該是表達清楚了。我自己寫了一段代碼,大概有20~30行的樣子,用Regex把數字提取出來,然後改掉,然後一段一段填回去。比較麻煩的地方,是修改字串之後,長度增加了,所以之前在提取字串的時候要自己處理當前插入位置之類的。
    Pass這道題之後,看了下Best solution:    def checkio(txt):        '''        string with comma separated numbers, which inserted after every third digit from right to left     '''        return re.sub(r'(?<=\d)(?=(\d\d\d)+\b)', '.', str(txt))
    看過之後發現自己對python的加強版Regex不夠熟悉,看了看這篇文章,補了補功課:    PythonRegex介紹    http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html        上面的解法非常巧妙,注意一點:(?=...)這種匹配模式是不消耗字元的,所以會形成迴圈匹配,正好達到了目的。我的意思是:如果不是迴圈匹配的話,加一個小數點之後可能就繼續下一個詞了。
    經過實驗,(?<=...)這種特殊構造有一個限制條件——必須是固定長度的,如果你寫(?<=.*?)這種條件,Python會報相應的異常。
————————————re.sub函數————————————————————    這個題的解法很巧妙,當然巧妙也意味著比較特別,通用性不強。    回到之前我的那個破代碼,貼出來瞅瞅:def checkio(txt):    '''    string with dot separated numbers, which inserted after every third digit from right to left    '''    l = []    beg = 0    for e in re.finditer(r'\b\d+\b', txt):        p1, p2 = e.span()        l.append( txt[beg:p1] )                 s = txt[p1:p2]        s2 = []        for i in range(len(s)-1, -1, -1):            s2.append(s[i])            if (len(s)-i) % 3 == 0 and i != 0:
                s2.append('.')        s2.reverse()        s = ''.join(s2)        l.append( s )                 beg = p2    l.append( txt[beg:] )    print ''.join(l)    return ''.join(l)    中間比較長的一段是給字串加小數點,假如抽出來不看的話,那麼多餘的地方就是 l、beg、p1、p2等幾個變數以及它們的計算了。    仔細玩了下re.findall和re.sub,發現它們尋找的方式不大一樣,主要是對括弧括起來的group處理不太一樣。這個問題以前也納悶過。今天恍然大悟:
    re.sub的第二個參數repl,可以是函數!
    如果自訂一個函數change(match),在使用re.sub時底層就會在尋找到合適的pattern時調用這個change函數。參數是一個match對象,記錄了group、span之類的東東。處理這個match對象返回一個字串,底層就會幫你把這個字串替換回去。    不容易說明白,試試就明白了。
    我用這個辦法修改了之前MB檔案處理的函數,簡潔了很多。re.sub函數的介面設計很自然,值得學習。以前竟然沒想到能這麼用,小自責一下。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.