$聊一聊"駝峯"和"下劃線"——Python re.sub函數詳細用法實例講解

平常寫代碼時候會遇到一些字符串替換的操做,好比把一大堆"駝峯"形式的字符串批量轉換成下劃線形式。"駝峯"形式的變量命名風格在Java中很常見,而下劃線形式的變量命名風格在C、Python等語言的代碼中更常見一些,二者沒有嚴格的好壞區分。本文就用"駝峯"和"下劃線"相互轉換的實例,講解一下Python的re模塊sub函數的強大功能。html

什麼是"駝峯"和"下劃線"風格的字符串

變量名、函數名等標識符的多個單詞之間用下劃線隔開,這樣的字符串就是下劃線風格的字符串,好比:python

person_info
ipv6_address
book_id
get_tomorrow_weather()

而駝峯風格的字符串就是不一樣單詞之間用大寫字母進行分隔,好比:正則表達式

personInfo
ipv6Address
bookId
getTomorrowWeather()

re.sub函數

re.sub函數是Python內置的re模塊的一個字符串替換函數,支持正則替換。函數文檔以下:json

help(re.sub)
Help on function sub in module re:
sub(pattern, repl, string, count=0, flags=0)
    Return the string obtained by replacing the leftmost
    non-overlapping occurrences of the pattern in string by the
    replacement repl.  repl can be either a string or a callable;
    if a string, backslash escapes in it are processed.  If it is
    a callable, it's passed the match object and must return
    a replacement string to be used.

re.sub函數的函數原型爲:sub(pattern, repl, string, count=0, flags=0)app

下面簡單介紹一下每一個參數的含義:函數

  • pattern:是一個正則表達式,匹配要替換的子串。測試

  • repl:能夠是一個字符串,支持對pattern中分組的後向引用。注意到文檔的最後一句話:code

If it is a callable, it's passed the match object and must return a replacement string to be used.htm

可見,repl也能夠是一個callable對象(函數),這個函數的入參爲pattern正則匹配到的對象,返回值爲一個字符串,表示要替換成的字符串。對象

注:正則的分組及後向引用詳見:python正則表達式系列(4)——分組和後向引用

  • string:要進行替換操做的字符串。

  • count:要替換掉多少個子串(按從左到右的順序),默認值爲0,表示替換能被pattern匹配到的全部子串。

  • flags:正則內置屬性,默認值爲0,表示不使用任何內置屬性。

注:正則內置屬性的用法詳見:python正則表達式系列(3)——正則內置屬性

"駝峯"和"下劃線"字符串之間的相互轉換

經過對re.sub函數的深刻了解,如今應該能夠輕鬆寫出"駝峯"和"下劃線"字符串相互轉換的代碼了。直接上代碼:

# coding:utf-8
import re

def hump2underline(hunp_str):
    '''
    駝峯形式字符串轉成下劃線形式
    :param hunp_str: 駝峯形式字符串
    :return: 字母全小寫的下劃線形式字符串
    '''
    # 匹配正則,匹配小寫字母和大寫字母的分界位置
    p = re.compile(r'([a-z]|\d)([A-Z])')
    # 這裏第二個參數使用了正則分組的後向引用
    sub = re.sub(p, r'\1_\2', hunp_str).lower()
    return sub

def underline2hump(underline_str):
    '''
    下劃線形式字符串轉成駝峯形式
    :param underline_str: 下劃線形式字符串
    :return: 駝峯形式字符串
    '''
    # 這裏re.sub()函數第二個替換參數用到了一個匿名回調函數,回調函數的參數x爲一個匹配對象,返回值爲一個處理後的字符串
    sub = re.sub(r'(_\w)',lambda x:x.group(1)[1].upper(),underline_str)
    return sub

代碼中已經有詳細的註釋,仍是比較好理解的。下面對這兩個函數進行測試:

def test_hump2underline():
    # 供測試用的一些駝峯形式的字符串
    attr1 = 'PersonNamePattern'
    attr2 = 'IPv6Address'
    attr3 = 'personDetailInfo'
    attr4 = 'CCTV'
    attr5 = 'CCTVAddress'
    attr6 = 'name'
    attrs = [attr1,attr2,attr3,attr4,attr5,attr6]

    # 遍歷attrs進行匹配和轉換,把駝峯形式的字符串轉成下劃線形式
    for attr in attrs:
        sub = hump2underline(attr)
        print sub

    # 輸出:
    '''
    person_name_pattern
    ipv6_address
    person_detail_info
    cctv
    cctvaddress
    name
    '''

def test_underline2hump():
    attr1 = 'person_name_pattern'
    attr2 = 'ipv6_address'
    attr3 = 'person_detail_info'
    attr4 = 'cctv'
    attr5 = 'cctvaddress'
    attr6 = 'name'
    attrs = [attr1, attr2, attr3, attr4, attr5, attr6]

    for attr in attrs:
        sub = underline2hump(attr)
        print sub

    # 輸出:
    '''
    personNamePattern
    ipv6Address
    personDetailInfo
    cctv
    cctvaddress
    name
    '''

JSON字符串字段名的"駝峯"轉"下劃線"

JSON是一種很是通用、輕量型的數據交換格式,與Python中的字典、Java中的Map具備相同的結構。JSON中的字段名通常須要寫成下劃線的形式,可是有時候也會遇到字段名是"駝峯"形式的JSON文本,那麼如何把一個JSON字符串中的全部字段名都從駝峯形式替換成下劃線形式呢?

由於考慮到json可能具備多層嵌套的複雜結構,因此下面直接採用正則文本替換的方式進行處理,而不是採用把JSON字符串轉成字典再進行處理。

上代碼:

def json_hump2underline(hump_json_str):
    '''
    把一個json字符串中的全部字段名都從駝峯形式替換成下劃線形式。
    注意點:由於考慮到json可能具備多層嵌套的複雜結構,因此這裏直接採用正則文本替換的方式進行處理,而不是採用把json轉成字典再進行處理的方式
    :param hump_json_str: 字段名爲駝峯形式的json字符串
    :return: 字段名爲下劃線形式的json字符串
    '''
    # 從json字符串中匹配字段名的正則
    # 注:這裏的字段名只考慮由英文字母、數字、下劃線組成
    attr_ptn = re.compile(r'"\s*(\w+)\s*"\s*:')

    # 使用hump2underline函數做爲re.sub函數第二個參數的回調函數
    sub = re.sub(attr_ptn,lambda x : '"' + hump2underline(x.group(1)) + '" :',hump_json_str)
    return sub

對上面這個函數進行測試:

def test_json_hump2underline():
    # 待測試json字符串
    json_str = '''
    {
        "englishName":"Tom",
        "age":18,
        "detailInfoTable": {
            "address":"USA",
            "sportsHobby": ["Basketball","Football","Swimming"],
            "contactList":{
                "tel" : "1234567",
                "emailAddress":"tom@test.com"
            }
        },
        "gender":"male"
    }
    '''
    print json_hump2underline(json_str)

    # 輸出:
    '''
    {
        "english_name" :"Tom",
        "age" :18,
        "detail_info_table" : {
            "address" :"USA",
            "sports_hobby" : ["Basketball","Football","Swimming"],
            "contact_list" :{
                "tel" : "1234567",
                "email_address" :"tom@test.com"
            }
        },
        "gender" :"male"
    }
    '''

總結

通過以上實例能夠看出,re.sub函數由於支持了正則替換及回調函數替換,在處理複雜文本替換需求時具備強大的優點,再一次展示了Python在文本處理領域功能強大又簡單、易用的特色。

相關文章
相關標籤/搜索