python05-正則表達式(一)

正則表達式

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

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

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

      • .:通配符(任意字符)
      • ^:是否以某個字符開頭
      • $:是否以某個字符結尾
      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']
      
      • \:轉義
        • 后面如果接元字符募逞,則將元字符轉為普通字符
        • 后面接普通字符倡怎,則實現(xià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():匹配的結束位置索引
    • span():start 和 end索引之間的區(qū)間
    ret = re.search('(ap)+(pl)+e', 'apple apaplele')
    print(ret.start())  # 從開始
    print(ret.end())    # index = 4結束假抄,開區(qū)間為5
    print(ret.span())   #[0,5)
    
    a = '123abc456'
    regex = '([\d]*)([a-zA-Z]*)([\d]*)'
    ret = re.search(regex, a)
    print(ret.group()) # 默認為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()) # 默認為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ù)怎栽,默認為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):替換宿饱,返回的結果帶替換次數(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):編譯.傳入一個正則表達式熏瞄,返回一個匹配器
    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正則表達式

# IP 正則表達式
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中,反斜杠\有轉義的含義谬以,當遇到\a根據(jù)ascii碼表强饮,會轉為有特殊含義的字符0x07響鈴符BEL
    • 解決:

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

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

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

      • 通過上面的寫法骤星,會很麻煩,于是就產(chǎn)生了遠程字符串的概念
      ret = re.findall(r'\\', r'abc\123') 
      # ['\\']其中一個是轉義爆哑,表示一個反斜杠
      
      • 代碼中,r表示后面字符串的內(nèi)容就是代表反斜杠舆吮,沒有別的意思揭朝,代碼執(zhí)行的時候,python把2個反斜杠原封不動的傳給正則色冀,正則拿到反斜杠潭袱,第一個用作第二個的轉義
      • 這樣代碼執(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轉義之后锋恬,傳到正則后是一個反斜杠
      • 一個反斜杠轉義d屯换,表示數(shù)字
      • 第二個通過r指定反斜杠是原生字符串,反斜杠直接傳到正則表達式轉義d
      • 第三個理論上會報錯与学,但是反斜杠d在ascii碼表上沒有特殊含義彤悔,python內(nèi)部會將其原封不動傳給正則表達式,但是如果遇到時\a之類的就報錯了
      • 所以嚴格來說按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']
    
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末索守,一起剝皮案震驚了整個濱河市晕窑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卵佛,老刑警劉巖杨赤,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異截汪,居然都是意外死亡疾牲,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進店門衙解,熙熙樓的掌柜王于貴愁眉苦臉地迎上來阳柔,“玉大人,你說我怎么就攤上這事蚓峦】” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵枫匾,是天一觀的道長架诞。 經(jīng)常有香客問我,道長干茉,這世上最難降的妖魔是什么谴忧? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上沾谓,老公的妹妹穿的比我還像新娘委造。我一直安慰自己,他們只是感情好均驶,可當我...
    茶點故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布昏兆。 她就那樣靜靜地躺著,像睡著了一般妇穴。 火紅的嫁衣襯著肌膚如雪爬虱。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天腾它,我揣著相機與錄音跑筝,去河邊找鬼。 笑死瞒滴,一個胖子當著我的面吹牛曲梗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播妓忍,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼虏两,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了世剖?” 一聲冷哼從身側響起碘举,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搁廓,沒想到半個月后引颈,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡境蜕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年蝙场,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片粱年。...
    茶點故事閱讀 39,932評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡售滤,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出台诗,到底是詐尸還是另有隱情完箩,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布拉队,位于F島的核電站弊知,受9級特大地震影響,放射性物質發(fā)生泄漏粱快。R本人自食惡果不足惜秩彤,卻給世界環(huán)境...
    茶點故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一叔扼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧漫雷,春花似錦瓜富、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蓄坏,卻和暖如春价捧,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背剑辫。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留渠欺,地道東北人妹蔽。 一個月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像挠将,于是被迫代替她去往敵國和親胳岂。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,884評論 2 354

推薦閱讀更多精彩內(nèi)容

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