python05-正則表達式(一)

正則表達式

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

    • import re # 引入re模塊調用正則表達式
  • 字符匹配

    • 普通字符:如英文字母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']
      
      • * :出現0次或n次
      • +:出現1次或n次
      • ?:出現0次或1次
      • {}:
        • {x}:出現x次
        • {x,}:至少出現x次
        • {x,y}:出現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']
      
      • \:轉義
        • 后面如果接元字符,則將元字符轉為普通字符
        • 后面接普通字符,則實現該字符特殊功能
        • 后面接序號,引用所匹配的字符串
      
      
        • -:表示范圍
        • ^:取反
        • \:轉義
          • \d:數字[1-9]
          • \D:非數字[^1-9]
          • \w:字母數字下劃線[a-zA-Z_]
          • \W:非字母數字下劃線[^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():只匹配開頭的內容
  • search() 和 match()如果匹配成功或返回一個對象,該對象方法

    • group():返回組的內容
    • groups():根據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索引之間的區間
    ret = re.search('(ap)+(pl)+e', 'apple apaplele')
    print(ret.start())  # 從開始
    print(ret.end())    # index = 4結束,開區間為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表示替換的最大次數,默認為0,不限次數
    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):替換,返回的結果帶替換次數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
  • 原生字符串

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

      • 在python中,反斜杠\有轉義的含義,當遇到\a根據ascii碼表,會轉為有特殊含義的字符0x07響鈴符BEL
    • 解決:

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

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

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

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

    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,表示數字
      • 第二個通過r指定反斜杠是原生字符串,反斜杠直接傳到正則表達式轉義d
      • 第三個理論上會報錯,但是反斜杠d在ascii碼表上沒有特殊含義,python內部會將其原封不動傳給正則表達式,但是如果遇到時\a之類的就報錯了
      • 所以嚴格來說按12的寫才是正確的
  • findall用法

    • findall優先把組里的內容取出來
    regex = 'www.(baidu|youku).com'
    ret = re.findall(regex, 'www.baidu.com')
    print(ret) # ['baidu']
    
    • 如果要去掉優先捕獲
    regex = 'www.(?:baidu|youku).com'
    ret = re.findall(regex, 'www.baidu.com')
    print(ret) # ['www.baidu.com']
    
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容

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