欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

python中正則表達式的使用詳解

系統 1627 0

從學習Python至今,發現很多時候是將Python作為一種工具。特別在文本處理方面,使用起來更是游刃有余。

說到文本處理,那么正則表達式必然是一個絕好的工具,它能將一些繁雜的字符搜索或者替換以非常簡潔的方式完成。

我們在處理文本的時候,或是查詢抓取,或是替換.

一.查找
如果你想自己實現這樣的功能模塊,輸入某一個ip地址,得到這個ip地址所在地區的詳細信息.

然后你發現http://ip138.com 可以查出很詳細的數據

但是人家沒有提供api供外部調用,但是我們可以通過代碼模擬查詢然后對結果進行抓取.

通過查看這個相應頁面的源碼,我們可以發現,結果是放在三個

  • 中的

    復制代碼 代碼如下:


    ?
    ??????? ?
    ???
    ?
    ??????? ?
    ???
    ?
    ?
    ??????? ?
    ???
    ?
    ??????? ?
    ?
    ???

    ?
    ??????? ?
    ???




    ? ??? ? ??? ? ??? ? ??? ? ??? ? ??? ? ? ??? ?

    ip138.com IP查詢(搜索IP地址的地理位置)

    您查詢的IP:121.0.29.231

    • 本站主數據:浙江省杭州市 阿里巴巴
    • 參考數據一:浙江省杭州市 阿里巴巴
    • 參考數據二:浙江省杭州市 阿里巴巴
    如果您發現查詢結果不詳細或不正確,請使用 IP數據庫自助添加 功能進行修正

    ?
    ???????

    IP地址或者域名:
    ???

    如果你了解正則表達式你可能會寫出

    正則表達式

    復制代碼 代碼如下:

    (?<=
  • ).*?(?=
  • )

    這里使用了前瞻:lookahead 后顧: lookbehind,這樣的好處就是匹配的結果中就不會包含html的li標簽了.

    如果你對自己寫的正則表達式不是很自信的話,可以在一些在線或者本地的正則測試工具進行一些測試,以確保正確.

    接下來的工作就是如果用Python實現這樣的功能,首先我們得將正則表達式表示出來:

    復制代碼 代碼如下:

    r"(?<=
  • ).*?(?=
  • )"?

    ?Python中字符串前面加上前導r這個字符,代表這個字符串是R aw String(原始字符串),也就是說Python字符串本身不會對字符串中的字符進行轉義.這是因為正則表達式也有轉義字符之說,如果雙重轉義的話,易讀性很差.

    這樣的串在Python中我們把它叫做"regular expression pattern"

    如果我們對pattern進行編譯的話

    復制代碼 代碼如下:

    prog = re.compile(r"(?<=
  • ).*?(?=
  • )")?

    我們便可以得到一個正則表達式對象regular expression object,通過這個對象我們可以進行相關操作.

    比如

    復制代碼 代碼如下:

    result=prog.match(string)?
    ##這個等同于?
    result=re.match(r"(?<=
  • ).*?(?=
  • )",string)?
    ##但是如果這個正則需要在程序匹配多次,那么通過正則表達式對象的方式效率會更高?

    接下來就是查找了,假設我們的html結果已經以html的格式存放在text中,那么通過

    復制代碼 代碼如下:

    result_list = re.findall(r"(?<=
  • ).*?(?=
  • )",text)?

    便可以取得所需的結果列表.

    二.替換
    使用正則表達式進行替換非常的靈活.

    比如之前我在閱讀Trac這個系統中wiki模塊的源代碼的時候,就發現其wiki語法的實現就是通過正則替換進行的.

    在使用替換的時候會涉及到正則表達式中的Group分組的概念.

    假設wiki語法中使用!表示轉義字符即感嘆號后面的功能性字符會原樣輸出,粗體的語法為

    寫道
    '''這里顯示為粗體'''
    ?那么有正則表達式為

    復制代碼 代碼如下:

    r"(?P !?''')"?

    ? 這里的?P 是Python正則語法中的一部分,表示其后的group的名字為"bold"

    ? 下面是替換時的情景,其中sub函數的第一個參數是pattern,第二個參數可以是字符串也可以是函數,如果是字符串的話,那么就是將目標匹配的結果替換成指定的結果,而如果是函數,那么函數會接受一個match object的參數,并返回替換后的字符串,第三個參數便是源字符串.

    復制代碼 代碼如下:

    result = re.sub(r"(?P !?''')", replace, line)?

    每當匹配到一個三單引號,replace函數便運行一次,可能這時候需要一個全局變量記錄當前的三單引號是開還是閉,以便添加相應的標記.

    在實際的trac wiki的實現的時候,便是這樣通過一些標記變量,來記錄某些語法標記的開閉,以決定replace函數的運行結果.

    --------------------

    示例

    一. 判斷字符串是否是全部小寫

    代碼

    復制代碼 代碼如下:

    # -*- coding: cp936 -*-
    import re?
    s1 = 'adkkdk'
    s2 = 'abc123efg'

    an = re.search('^[a-z]+$', s1)
    if an:
    ??? print 's1:', an.group(), '全為小寫'
    else:
    ??? print s1, "不全是小寫!"

    an = re.match('[a-z]+$', s2)
    if an:
    ??? print 's2:', an.group(), '全為小寫'
    else:
    ??? print s2, "不全是小寫!"

    結果

    ?

    究其因

    1. 正則表達式不是python的一部分,利用時需要引用re模塊

    2. 匹配的形式為: re.search(正則表達式, 帶匹配字串)或re.match(正則表達式, 帶匹配字串)。兩者區別在于后者默認以開始符(^)開始。因此,

    re.search('^[a-z]+$', s1) 等價于 re.match('[a-z]+$', s2)
    3. 如果匹配失敗,則an = re.search('^[a-z]+$', s1)返回None

    group用于把匹配結果分組

    例如

    復制代碼 代碼如下:

    import re
    a = "123abc456"
    print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)?? #123abc456,返回整體
    print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)?? #123
    print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)?? #abc
    print re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)?? #456

    1)正則表達式中的三組括號把匹配結果分成三組

      group() 同group(0)就是匹配正則表達式整體結果

      group(1) 列出第一個括號匹配部分,group(2) 列出第二個括號匹配部分,group(3) 列出第三個括號匹配部分。

    2)沒有匹配成功的,re.search()返回None

    3)當然鄭則表達式中沒有括號,group(1)肯定不對了。

    二.? 首字母縮寫詞擴充

    具體示例

    FEMA?? Federal Emergency Management Agency
    IRA??? Irish Republican Army
    DUP??? Democratic Unionist Party

    FDA??? Food and Drug Administration
    OLC??? Office of Legal Counsel
    分析

    縮寫詞  FEMA
    分解為  F*** E*** M*** A***
    規律  ? 大寫字母 + 小寫(大于等于1個)+ 空格
    參考代碼

    復制代碼 代碼如下:

    import re
    def expand_abbr(sen, abbr):
    ??? lenabbr = len(abbr)
    ??? ma = ''
    ??? for i in range(0, lenabbr):
    ??????? ma += abbr[i] + "[a-z]+" + ' '
    ??? print 'ma:', ma
    ??? ma = ma.strip(' ')
    ??? p = re.search(ma, sen)
    ??? if p:
    ??????? return p.group()
    ??? else:
    ??????? return ''

    print expand_abbr("Welcome to Algriculture Bank China", 'ABC')

    結果

    問題

    上面代碼對于例子中的前3個是正確的,但是后面的兩個就錯了,因為大寫字母開頭的詞語之間還夾雜著小寫字母詞

    規律

    大寫字母 + 小寫(大于等于1個)+ 空格 + [小寫+空格](0次或1次)

    參考代碼

    復制代碼 代碼如下:

    import re
    def expand_abbr(sen, abbr):
    ??? lenabbr = len(abbr)
    ??? ma = ''
    ??? for i in range(0, lenabbr-1):
    ??????? ma += abbr[i] + "[a-z]+" + ' ' + '([a-z]+ )?'
    ??? ma += abbr[lenabbr-1] + "[a-z]+"
    ??? print 'ma:', ma
    ??? ma = ma.strip(' ')
    ??? p = re.search(ma, sen)
    ??? if p:
    ??????? return p.group()
    ??? else:
    ??????? return ''

    print expand_abbr("Welcome to Algriculture Bank of China", 'ABC')

    技巧

    中間的 小寫字母集合+一個空格,看成一個整體,就加個括號。要么同時有,要么同時沒有,這樣需要用到?,匹配前方的整體。

    三. 去掉數字中的逗號

    具體示例

    在處理自然語言時123,000,000如果以標點符號分割,就會出現問題,好好的一個數字就被逗號肢解了,因此可以先下手把數字處理干凈(逗號去掉)。

    分析

    數字中經常是3個數字一組,之后跟一個逗號,因此規律為:***,***,***

    正則式

    [a-z]+,[a-z]?

    參考代碼3-1

    復制代碼 代碼如下:

    import re

    sen = "abc,123,456,789,mnp"
    p = re.compile("\d+,\d+?")

    for com in p.finditer(sen):
    ??? mm = com.group()
    ??? print "hi:", mm
    ??? print "sen_before:", sen
    ??? sen = sen.replace(mm, mm.replace(",", ""))
    ??? print "sen_back:", sen, '\n'

    結果

    python中正則表達式的使用詳解_第1張圖片

    技巧

    使用函數finditer(string[, pos[, endpos]]) | re.finditer(pattern, string[, flags]):

    搜索string,返回一個順序訪問每一個匹配結果(Match對象)的迭代器。?????

    參考代碼3-2

    復制代碼 代碼如下:

    sen = "abc,123,456,789,mnp"
    while 1:
    ??? mm = re.search("\d,\d", sen)
    ??? if mm:
    ??????? mm = mm.group()
    ??????? sen = sen.replace(mm, mm.replace(",", ""))
    ??????? print sen
    ??? else:
    ??????? break

    結果

    延伸

    這樣的程序針對具體問題,即數字3位一組,如果數字混雜與字母間,干掉數字間的逗號,即把“abc,123,4,789,mnp”轉化為“abc,1234789,mnp”

    思路

    更具體的是找正則式“數字,數字”找到后用去掉逗號的替換

    參考代碼3-3

    復制代碼 代碼如下:

    sen = "abc,123,4,789,mnp"
    while 1:
    ??? mm = re.search("\d,\d", sen)
    ??? if mm:
    ??????? mm = mm.group()
    ??????? sen = sen.replace(mm, mm.replace(",", ""))
    ??????? print sen
    ??? else:
    ??????? break
    print sen

    結果

    四. 中文處理之年份轉換(例如:一九四九年--->1949年)

    中文處理涉及到編碼問題。例如下邊的程序識別年份(****年)時

    復制代碼 代碼如下:

    # -*- coding: cp936 -*-
    import re
    m0 =? "在一九四九年新中國成立"
    m1 =? "比一九九零年低百分之五點二"
    m2 =? '人一九九六年擊敗俄軍,取得實質獨立'

    def fuc(m):
    ??? a = re.findall("[零|一|二|三|四|五|六|七|八|九]+年", m)
    ??? if a:
    ??????? for key in a:
    ??????????? print key
    ??? else:
    ??????? print "NULL"

    fuc(m0)
    fuc(m1)
    fuc(m2)

    運行結果

    可以看出第二個、第三個都出現了錯誤。

    改進――準化成unicode識別

    復制代碼 代碼如下:

    # -*- coding: cp936 -*-
    import re
    m0 =? "在一九四九年新中國成立"
    m1 =? "比一九九零年低百分之五點二"
    m2 = '人一九九六年擊敗俄軍,取得實質獨立'

    def fuc(m):
    ??? m = m.decode('cp936')
    ??? a = re.findall(u"[\u96f6|\u4e00|\u4e8c|\u4e09|\u56db|\u4e94|\u516d|\u4e03|\u516b|\u4e5d]+\u5e74", m)

    ??? if a:
    ??????? for key in a:
    ??????????? print key
    ??? else:
    ??????? print "NULL"

    fuc(m0)
    fuc(m1)
    fuc(m2)

    結果

    識別出來可以通過替換方式,把漢字替換成數字。

    參考

    復制代碼 代碼如下:

    numHash = {}
    numHash['零'.decode('utf-8')] = '0'
    numHash['一'.decode('utf-8')] = '1'
    numHash['二'.decode('utf-8')] = '2'
    numHash['三'.decode('utf-8')] = '3'
    numHash['四'.decode('utf-8')] = '4'
    numHash['五'.decode('utf-8')] = '5'
    numHash['六'.decode('utf-8')] = '6'
    numHash['七'.decode('utf-8')] = '7'
    numHash['八'.decode('utf-8')] = '8'
    numHash['九'.decode('utf-8')] = '9'

    def change2num(words):
    ??? print "words:",words
    ??? newword = ''
    ??? for key in words:
    ??????? print key
    ??????? if key in numHash:
    ??????????? newword += numHash[key]
    ??????? else:
    ??????????? newword += key
    ??? return newword

    def Chi2Num(line):
    ??? a = re.findall(u"[\u96f6|\u4e00|\u4e8c|\u4e09|\u56db|\u4e94|\u516d|\u4e03|\u516b|\u4e5d]+\u5e74", line)
    ??? if a:
    ??????? print "------"
    ??????? print line
    ??????? for words in a:
    ??????????? newwords = change2num(words)
    ??????????? print words
    ??????????? print newwords
    ??????????? line = line.replace(words, newwords)
    ??? return line


    更多文章、技術交流、商務合作、聯系博主

    微信掃碼或搜索:z360901061

    微信掃一掃加我為好友

    QQ號聯系: 360901061

    您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

    【本文對您有幫助就好】

    您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

    發表我的評論
    最新評論 總共0條評論
    主站蜘蛛池模板: 国产精品美女久久久久久久久久久 | 亚洲精品视频在线 | 婷婷久久综合九色综合九七 | 久久精品人人做人人看最新章 | 日韩高清中文字幕 | 天天综合亚洲 | 精品国产一区二区三区久久久蜜月 | 免费观看一级黄色片 | 国产精品亚洲综合色拍 | 亚洲国产天堂久久综合9999 | 奇米影视888狠狠狠777不卡 | 色综合天天综合网国产成人网 | 亚洲欧美中文日韩在线 | 婷婷色中文字幕 | 色射综合 | 久久这里只有精品免费看青草 | 亚洲日本va | 欧美日韩视频 | 欧美乱大交xxxx | 国产精品二区三区 | 一区二区三区免费看 | 国产一级免费在线观看 | 91精品国产闺蜜国产在线 | wwwxx免费| 久久亚洲精品中文字幕二区 | 国产精品视频网 | 五月天丁香久久 | 91美女在线观看 | 91传媒蜜桃香蕉在线观看 | 在线观看黄色小视频 | 高清国语自产拍免费视频国产 | 午夜男人女人爽爽爽视频 | 日本夜爽爽一区二区三区 | 免费国产黄频在线观看视频 | 国产精品久久久久久久免费大片 | 国产精品乱码一区二三区小蝌蚪 | 日韩中文字幕一区二区三区 | 亚洲美女网站 | 偷拍自拍网址 | 91免费版在线看 | 水野朝阳128部合集在线 |