python05-正則表達(dá)式(一)

正則表達(dá)式

  • python無正則表達(dá)式,通過別的模塊re(regex模塊)應(yīng)用過來

    • import re # 引入re模塊調(diào)用正則表達(dá)式
  • 字符匹配

    • 普通字符:如英文字母a-zA-Z和其他字符
    regex = 'apple'
    ret = re.findall(regex, 'i have a apple , i have a pen, apple pen ?')
    print(ret)
    ======>
    ['apple', 'apple']
    
    • 元字符:被賦予特殊含義的字符

      • .:通配符(任意字符)
      • ^:是否以某個字符開頭
      • $:是否以某個字符結(jié)尾
      ret = re.findall('.', 'string')
      print(ret) # ['s', 't', 'r', 'i', 'n', 'g']
      
      ret = re.findall("^apple", 'apple is one kind of fruit')
      print(ret) # ['apple']
      ret = re.findall("^apple", 'the apple is one kind of fruit')
      print(ret) # []
      
      ret = re.findall('pen$', 'i have a apple , i have a pen, apple pen ?')
      print(ret) # []
      ret = re.findall('pen$', 'i have a apple , i have a pen, apple pen')
      print(ret) # ['pen']
      
      • * :出現(xiàn)0次或n次
      • +:出現(xiàn)1次或n次
      • ?:出現(xiàn)0次或1次
      • {}:
        • {x}:出現(xiàn)x次
        • {x,}:至少出現(xiàn)x次
        • {x,y}:出現(xiàn)x-y次之間
      ret = re.findall('apple*', 'i have an apple , not applee or appl')
      print(ret) # ['apple', 'applee', 'appl']
      ret = re.findall('apple+', 'i have an apple , not applee or appl')
      print(ret) # ['apple', 'applee']
      ret = re.findall('apple?', 'i have an apple , not applee or appl')
      print(ret) # ['apple', 'apple', 'appl']
      ret = re.findall('apple{2,4}','i have an apple , not appleee or appleeee')
      print(ret) # ['appleee', 'appleeee']
      
      • \:轉(zhuǎn)義
        • 后面如果接元字符,則將元字符轉(zhuǎn)為普通字符
        • 后面接普通字符,則實現(xiàn)該字符特殊功能
        • 后面接序號,引用所匹配的字符串
      
      
        • -:表示范圍
        • ^:取反
        • \:轉(zhuǎn)義
          • \d:數(shù)字[1-9]
          • \D:非數(shù)字[^1-9]
          • \w:字母數(shù)字下劃線[a-zA-Z_]
          • \W:非字母數(shù)字下劃線[^a-zA-Z_]
          • \s:空白字符[\t\n\r\f\v]
          • \S:非空白字符[\t\n\r\f\v]
          • \b:匹配單個單詞邊界,就是單詞間間隔,邊界不一定是空格,特殊字符也可以
        • ():組
      ret = re.findall('\d', '123sadf@#$')
      print(ret) # ['1', '2', '3']
      ret = re.findall('[^\d]+','asdf123d5esd234')
      print(ret) # ['asdf', 'd', 'esd']
      
      ret = re.search(r'(alex)(eric)com\1', 'alexericcomalex').group()
      print(ret) # alexericcomalex
      
      • 非貪婪匹配
        • 一般 *和+匹配的時候都按照最多的原則匹配獲取(貪婪匹配)
        • 如果想要按最少匹配,則加上?但是有條件
      \d+?:一個或者多個,取最少的1個
      \d*?:0個或者多個,取最少的0個
      'a(\d+?)':可以用非貪婪匹配
      'a(\d+?)b'不可以用非貪婪模式,因為后面接了字符
      
  • re包方法:

    • findall():查找所有,返回一個列表
    • search():找到第一個就不往下找了
    • match():只匹配開頭的內(nèi)容
  • search() 和 match()如果匹配成功或返回一個對象,該對象方法

    • group():返回組的內(nèi)容
    • groups():根據(jù)regex的分組情況返回tuple
    ret = re.search('(ap)+(pl)+e', 'apple apaplele').group()
    print(ret) # apple
    ret = re.search('(ap)+(pl)+e', 'apple apaplele').groups()
    print(ret) # ('ap', 'pl')
    
    • start():匹配到的第一個索引位置
    • end():匹配的結(jié)束位置索引
    • span():start 和 end索引之間的區(qū)間
    ret = re.search('(ap)+(pl)+e', 'apple apaplele')
    print(ret.start())  # 從開始
    print(ret.end())    # index = 4結(jié)束,開區(qū)間為5
    print(ret.span())   #[0,5)
    
    a = '123abc456'
    regex = '([\d]*)([a-zA-Z]*)([\d]*)'
    ret = re.search(regex, a)
    print(ret.group()) # 默認(rèn)為0
    print(ret.group(1))
    print(ret.group(2))
    print(ret.group(3))
    print(ret.groups())
    """
    123abc456
    123
    abc
    456
    ('123', 'abc', '456')
    """
    a = '123abc456'
    regex = '([\d])*([a-zA-Z])*([\d])*'
    ret = re.search(regex, a)
    print(ret.group()) # 默認(rèn)為0
    print(ret.group(1))
    print(ret.group(2))
    print(ret.group(3))
    print(ret.groups())
    """
    123abc456
    3
    c
    6
    ('3', 'c', '6')
    """
    
  • re的其他方法:

    • sub(pattern, repl, string, max=0):替換
      • max表示替換的最大次數(shù),默認(rèn)為0,不限次數(shù)
    ret = re.sub('g.t', 'have', 'i get a pen, i got a pen, i gun a pen')
    print(ret) # i have a pen, i have a pen, i gun a pen
    
    • subn(pattern, repl, string):替換,返回的結(jié)果帶替換次數(shù)num
    ret = re.subn('g.t', 'have', 'i get a pen, i got a pen, i gun a pen')
    print(ret) # ('i have a pen, i have a pen, i gun a pen', 2)
    
    • compile(regext):編譯.傳入一個正則表達(dá)式,返回一個匹配器
    regex = re.compile('\w*oo\w*')
    ret = regex.findall('JGood is a handsome boy, he is cool')
    print(ret) # ['JGood', 'cool']
    
    • split:切割
    ret = re.split('\d', 'one1two2three3four4')
    print(ret) # ['one', 'two', 'three', 'four', '']
    
  • IP正則表達(dá)式

# IP 正則表達(dá)式
regex = '(([01]?\d?\d|2[0-4]\d|25\d)\.){3}([01]?\d?\d|2[0-4]\d|25\d)'
ret = re.search(regex, '192.168.97.196').group()
print(ret) # 192.168.97.196
  • 原生字符串

    • 執(zhí)行下面的代碼會報錯(在python中)
    file = open('C:\tmp\abc.txt', mode='r')
    # OSError: [Errno 22] Invalid argument: 'C:\tmp\x07bc.txt'
    
    • 原因:

      • 在python中,反斜杠\有轉(zhuǎn)義的含義,當(dāng)遇到\a根據(jù)ascii碼表,會轉(zhuǎn)為有特殊含義的字符0x07響鈴符BEL
    • 解決:

      • file = open(r'C:\tmp\abc.txt', mode='r')
      • r為rawString = 原生字符串,表示傳入python的字符是原生的,沒有特殊的含義
    • 執(zhí)行下面的代碼會報錯(在正則中)

    re.findall('\', 'abc\123') # 編譯的時候就會出錯
    
    • 原因:

      • 反斜杠\在正則中也有轉(zhuǎn)義的效果,代表后面接的字符有特殊含義
      • 所以使其表示反斜杠應(yīng)寫成\\(雙反斜杠,第一個用作轉(zhuǎn)義)
       re.findall('\\', 'abc\123') # 執(zhí)行會報錯
      
      • 代碼在正則下匹配是正確的,但是執(zhí)行代碼,程序會報錯
      • 原因:
        • 雖然正則表示的寫法是正確的,但是程序是運行在python下的
        • 在python代碼中,我們寫的是\\(雙反斜杠)表示反斜杠,這只是在python代碼中
        • 當(dāng)python代碼傳遞過去給正則表達(dá)式,其實是一條反斜杠的轉(zhuǎn)義符,但是正確的表達(dá)式需要2條,所以python代碼需要寫成4條反斜杠才能匹配成功
      • 修改代碼后為:
       re.findall('\\\\', 'abc\123') # ok
      
    • 原生字符串r的產(chǎn)生

      • 通過上面的寫法,會很麻煩,于是就產(chǎn)生了遠(yuǎn)程字符串的概念
      ret = re.findall(r'\\', r'abc\123') 
      # ['\\']其中一個是轉(zhuǎn)義,表示一個反斜杠
      
      • 代碼中,r表示后面字符串的內(nèi)容就是代表反斜杠,沒有別的意思,代碼執(zhí)行的時候,python把2個反斜杠原封不動的傳給正則,正則拿到反斜杠,第一個用作第二個的轉(zhuǎn)義
      • 這樣代碼執(zhí)行的時候會更加直觀
    • 執(zhí)行下面代碼

    ret = re.findall('\\d', 'w3t5e7')
    print(ret)
    ret = re.findall(r'\d', 'w3t5e7')
    print(ret)
    ret = re.findall('\d', 'w3t5e7')
    print(ret)
    ========
    ['3', '5', '7']
    ['3', '5', '7']
    ['3', '5', '7']
    
    • 原因:
      • 第一個傳入兩個反斜杠,python轉(zhuǎn)義之后,傳到正則后是一個反斜杠
      • 一個反斜杠轉(zhuǎn)義d,表示數(shù)字
      • 第二個通過r指定反斜杠是原生字符串,反斜杠直接傳到正則表達(dá)式轉(zhuǎn)義d
      • 第三個理論上會報錯,但是反斜杠d在ascii碼表上沒有特殊含義,python內(nèi)部會將其原封不動傳給正則表達(dá)式,但是如果遇到時\a之類的就報錯了
      • 所以嚴(yán)格來說按12的寫才是正確的
  • findall用法

    • findall優(yōu)先把組里的內(nèi)容取出來
    regex = 'www.(baidu|youku).com'
    ret = re.findall(regex, 'www.baidu.com')
    print(ret) # ['baidu']
    
    • 如果要去掉優(yōu)先捕獲
    regex = 'www.(?:baidu|youku).com'
    ret = re.findall(regex, 'www.baidu.com')
    print(ret) # ['www.baidu.com']
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 正則表達(dá)式(二) re模塊(regex) python中沒有正則表達(dá)式的函數(shù),需要引入內(nèi)置的re模塊 re模塊方法...
    AndroidCat閱讀 412評論 0 0
  • 1.正則表達(dá)式概述 正則表達(dá)式,又稱正規(guī)表示式、正規(guī)表示法、正規(guī)表達(dá)式、規(guī)則表達(dá)式、常規(guī)表示法(英語:Regula...
    TENG書閱讀 985評論 0 1
  • (一)定義 正則表達(dá)式是對字符串(包括普通字符(例如,a 到 z之間的字母)和特殊字符(稱為“元字符”))操作的一...
    a荷包蛋閱讀 593評論 0 0
  • re模塊手冊 本模塊提供了和Perl里的正則表達(dá)式類似的功能,不關(guān)是正則表達(dá)式本身還是被搜索的字符串,都可以...
    喜歡吃栗子閱讀 4,183評論 0 13
  • 一說到曹操大家肯定都想到奸炸,這可能是曹操在三國的人氣不好。有時演個戲,曹操一敗觀眾就連口稱贊,一聽劉備打了敗...
    kanzihan閱讀 327評論 0 0

友情鏈接更多精彩內(nèi)容