正則表達式常用方法

正則切割

import re
c =re.compile(r'\d')
s='hello52bthg235gfre'
ret=c.split(s,count=2)
print(ret)

正則替換

import re

r='sd7fB2dv2B1cfB;'
d=re.sub('\d','&',r,count=2)
print(d)#替換,及指定替換次數,不指定就全部替換

s = "1abc23def45"
#用?將s中符合r"\w"匹配的替換,打印替換後的結果及替換個數在一個元組內。
print(str(re.subn(r"\w", "?", s)[1]))#可以在中括號內輸入下標選擇打印


#替換
c =re.compile(r'\d')
s='hello52bthg235gfre'
ret=c.sub('&',s,count=2)
print(ret)
#封裝調用函數人爲干預替換過程
def double(s):
    print(s)
    return str(int(s.group())*2)
##先用正則公式對字符串進行匹配,匹配到後對應給要替換的位置參數,一看是函數把正則結果返回到函數進行處理獲取返回值進行替換
d=re.sub(r'\d', double, 'dg2hfgh4fh')

應用場景

  • 特定規律字符串的查找切割替換等
  • 郵箱格式、URL、IP等的校驗
  • 爬蟲項目中,特定內容的提取

使用原則

  • 只要使用字符串等函數解決的問題,就不要使用正則
  • 正則的效率比較低,同時會降低代碼的可讀性。
  • 世界上最難理解的三樣東西:醫生的處方、道士的神符、碼農的正則。
  • 提醒:正則是用來寫的,不是用來讀的;在不指定功能的情況下,不要試圖閱讀別人的正則。

基本使用match/search/findall/compile

  • 說明:正則不是我們寫的,python中正則的解析通過re模塊完成
  • 相關函數:
    • match:從開頭進行匹配,匹配到就返回正則結果對象,沒有返回None。

    • search:從任意位置匹配,功能同上。
      #從開頭查找,找到返回正則匹配結果對象,沒有找到返回None
      #m = re.match(‘abc’, ‘abcdask;jabcsdajl’)
      #從任意位置查找,功能同上
      m = re.search(‘abc’, ‘shdalsjdabchaoeor’)

      if m:
      # 返回匹配的內容
      print(m.group())
      # 返回匹配內容位置
      print(m.span())

    • findall:全部匹配,返回匹配到的內容組成的列表,沒有返回空列表。
      #先生成正則表達式對象
      c =re.compile(‘hello’)
      #從開頭匹配
      x =c.match(‘scdvdshello;csd55’)
      #從任意位置查找
      z =c.search(‘scdvdshello;csd55’)
      #返回所有匹配內容的列表,若沒找到返回空列表
      #f =c.findall(‘scdvdshello;csd55’)
      f =re.findall(‘ab’,‘scabvdshelablo;csabd55’)
      #與上邊等同
      f =re.findall(’(ab)’,‘scdvabdshabello;csabd5’)
      #按照正則公式整體查找但是隻打印括號內的,有多個括號時匹配到打印各個括號內的內容到一個元組內
      f =re.findall(‘sd(ab)hn’,‘ssdabhnllsdabhn5’)
      [‘ab’, ‘ab’]
      f =re.findall(‘sd(ab)h(ab)n’,‘ssdabhabn5’)
      [(‘ab’, ‘ab’)]
      #先按照最外邊括號匹配找到打印括號內內容,再去掉外邊括號再次匹配打印
      f =re.findall(’(sd(ab)h(ab)n)’,‘ssdabhabn5sdabhabn’)
      [(‘sdabhabn’, ‘ab’, ‘ab’), (‘sdabhabn’, ‘ab’, ‘ab’)]
      #按照括號裏的或語法依次匹配打印
      f =re.findall(‘a(hello|world)c’,‘sahellochg25aworldcn’)
      [‘hello’, ‘world’]
      #先匹配外部括號再去掉外部括號再次匹配分別打印到元組
      f =re.findall(’(a(hello|world)c)’,‘sahellochg25aworldcn’)
      [(‘ahelloc’, ‘hello’), (‘aworldc’, ‘world’)]
      print(f)

      #匹配所有內容,找到返回所有匹配的內容列表,沒有找到返回空列表
      f = re.findall(‘abcd’, ‘adsjkjdabcajsdlasabcjsdlaabc’)
      print(f)

    • compile:生成正則表達式對象
      #先生成正則表達式對象
      c = re.compile(‘hello’)
      #print(type©)

      #從開頭匹配
      m = c.match(‘hellosadk;ask;kahellosadhlkas’)
      print(m)

      #從任意位置匹配
      s = c.search(‘hadlsjasdhellokjsdlks’)
      print(s)

      #匹配所有內容
      f = c.findall(‘hellosdhasdjahelloshdajldhello’)
      print(f)
      說明:此方式更加靈活,將正則匹配分爲兩步完成(先生成正則對象,然後需要時進行匹配)

正則規則

單個字符\d \B [ ]

普通字符:簡單來說就是一對一的完全匹配。
[]:中間的任意一個字符
	[a-z]:a~z之間的任意字符(所有的小寫字母)
	[a-zA-Z]:匹配所有的字母,多個連續的片段中間不能有任何多餘的字符
	[^0-9]:匹配除0-9以外的任意字符
. :匹配除'\n'以外的任意字符
\d:數字字符,等價於[0-9]
\D:非數字字符,等價於[^0-9]
\w:匹配字(數字、字母、下劃線、漢字)
\W:匹配非字(\w相反的內容)
\s:所有的空白字符(\n、\t、\r、空格)
\S:非空白字符(\s相反的內容)
\b:詞邊界(開頭、結尾、空格、標點等)
\B:非詞邊界(\b相反的內容)

次數限定+ ? {m,n}

*:前面的字符出現任意次
+:至少一次
?:最多一次
{m,n}:m <= 次數 <= n
{m,}:至少m次
{,n}:至多n次
{m}:指定m次

邊界限定:^ $

  • ^:以指定的內容開頭

  • $:以指定的內容結束

  • 示例:

    import re

    #^:以指定內容開頭
    #f = re.findall(’^hello’, ‘hellosjdhelloalskdhello’)

    #$以指定內容結尾
    f = re.findall(‘hello$’, ‘hellosjdhelloalskdhello’)

    print(f)

優先級控制:’|’

  • |:表示或,它擁有最低的優先級

  • ():表示一個整體,可以明確的指定結合性/優先級

  • 示例:

    import re

    f = re.findall(‘a(hello|world)c’, ‘sahdjsahellocaworldcjsdhs’)

    print(f)

分組匹配:\1

  • 示例1:

    import re

    c = re.compile(r’(\d+)([a-z]+)(\d+)’)

    s = c.search(‘sdsdj235sadhasjd36432sjdha’)

    #完整匹配結果
    print(s.group(), s.span())
    #等價於上式
    print(s.group(0), s.span(0))
    #第幾個()匹配的結果
    print(s.group(1), s.span(1))
    print(s.group(2), s.span(2))
    print(s.group(3), s.span(3))

  • 示例2:

    import re

    #固定匹配
    #c = re.compile(r’\w+</\1>’)

    #\1表示前面第一個()匹配的內容
    #c = re.compile(r’<([a-z]+)><([a-z]+)>\w+</\2></\1>’)

    #給分組()起名字
    c = re.compile(r’<(?P[a-z]+)><(?P[a-z]+)>\w+</(?P=dahua)></(?P=goudan)>’)

    s = c.search(’<div><a>百度一下</a></div>’)

    if s:
    print(s.group())

貪婪匹配

  • 貪婪:最大限度的匹配。正則的匹配默認就是貪婪的。

  • 非貪婪:只要滿足條件,能少匹配就少匹配。’?'經常用於取消貪婪

  • 示例:

    import re
    
    # ?:取消任意多次的貪婪匹配
    # c = re.compile(r'a.*?b')#可以沒有,從左側開始符合就返回儘可能的少匹配
    
    # ?:取消至少一次的貪婪匹配
    c = re.compile(r'a.+?b')#至少要有一個,從左側開始符合就返回儘可能的少匹配
    
    s = c.search('ssjdsdabjdsd')
    
    if s:
        print(s.group()) 
    

匹配模式re.I忽略大小寫/re.M多行匹配/re.S作爲單行處理,忽略\n

  • 說明:所謂匹配模式就是對匹配的原則進行整體的修飾。

  • 示例:

    import re

    #忽略大小寫re.I
    s = re.search(r’hello’, ‘HELLO world’, re.I)

    #正則默認是單行匹配,使用 re.M 可以進行多行匹配
    s = re.search(r’^hello’, ‘sdhasdh\nhello world’, re.M)

    #使.匹配任意字符,作爲單行處理,忽略\n
    #string = ‘<div>hello</div>’
    string = ‘’’<div>
    hello
    </div>’’’
    s = re.search(r’<div>.*?</div>’, string, re.S)

    if s:
    print(s.group())

    import re

    m=re.match(‘abc’,‘vvvcxdabc52ff2d…’)#只從開頭查找
    print(m)
    n=re.search(‘abc’,‘vvvcxdabc52ff2d…’)#從任意位置查找
    print(n)

    if m:
    print(m.group())#打印匹配內容
    print(m.span())#打印匹配內容位置

    f = re.findall(‘abc’,‘5abc1cdfdabc2abc15f.;’)
    print(f)#返回所有匹配內容的列表,若沒找到返回空列表

    #先生成正則表達式對象
    c =re.compile(‘hello’)

    #從開頭匹配
    x =c.match(‘scdvdshello;csd55’)
    #從任意位置查找
    z =c.search(‘scdvdshello;csd55’)
    #返回所有匹配內容的列表,若沒找到返回空列表
    f =c.findall(‘scdvdshello;csd55’)

    #單個字符
    #匹配連續字符,[]中間的任意一個字符
    #[a-z]:a~z之間的任意一個字母
    c=re.compile(’[sdc]’)
    d=re.compile(’[a-z]’)
    #匹配所有的字母,多個連續的片段中間
    #不能有任何多餘的字符
    e=re.compile(’[a-zA-Z]’)
    #匹配相反的字符(除指定的字符以外的)
    #加上個’^‘箭頭
    g=re.compile(’[^fas]’)
    #’.‘匹配出’\n’以外的任意字符
    o=re.compile(’.’)

    #\d只匹配0~9的數字
    k=re.compile(’\d’)
    #\D匹配除數字以外的字符

    #\w匹配字(數字,字母,下劃線,漢字)

    #\W非字以外的字符

    #\s所有的空白字符(\n,\t,\r空格)
    j=re.compile(’\s’)
    v=c.findall(‘scfvsa sfv\ndcs’)
    #\S非空白字符

    #\b詞邊界\b在python中有特殊意義需要加r
    l=re.compile(r’\bhello’)
    n=c.findall(‘helloscfvs,helloavdcshello’)
    #\B非詞邊界

    #用控制字符可以出現任意次
    h=re.findall('ab
    c’,‘savdfdbbabbcbbabcbbfvwe’)
    #要求某字符至少出現一次
    m=re.findall(‘ab+c’,‘savdfdbbabbcbbabcbbfvwe’)
    #要求至多一次
    q=re.findall(‘ab?c’,‘savdfdbbabbcbbabcbbfvse’)
    #指定出現次數
    p=re.findall(‘ab{3}c’,‘savdfdbbabbcbbabcbbfse’)
    #指定出現次數的範圍,包括邊界[1,3]
    r=re.findall(‘ab{1,3}c’,‘sdavdfdbbabfvswe’)
    #指定至多多少次
    s=re.findall(‘ab{0,3}c’,‘sdavdfdbbabbbcbswe’)
    #指定至少多少次
    t=re.findall(‘ab{3,}c’,‘sdavdfdbbabbbcbbbfvswe’)

    #邊界限定
    #以指定內容開頭
    t=re.findall(’^hello’,‘hellosdafdbhellobfvswe’)
    #以指定內容結尾
    u=re.findall(‘hello$’,‘hellosdafdbhellobhello’)

    #優先級控制
    #指定內容有多個時,’|'它擁有最低優先級出現hello或world或兩個都有都可以
    w=re.findall(‘hello|world’,‘hellosdafdbhworldellllo’)
    #a和c之間出現hello或world,只能有兩個中的一個
    y=re.findall(‘a(hello|world)c’,‘hellosdafdbhworldellllo’)
    print(w)

    #分組匹配

    #固定匹配:\1代表前邊第一個括號內的內容
    j=re.compile(r’<([a-z]+)>\w+</\1>’)
    s=j.search(’<a>百度</a>’)

    j=re.compile(r’<([a-z]+)><([a-z]+)>\w+</\2></\1>’)
    s=j.search(’<div><a>百度</a></div>’)

    #給分組()起名字
    j=re.compile(r’<(?P[a-z]+)><([a-z]+)>\w+</\2></(?P=hello)>’)
    s=j.search(’<div><a>百度</a></div>’)

    #貪婪匹配
    n=re.compile(r’a.b’)
    m=n.search(‘cdfadfdacvbdvd’) #儘可能多的匹配
    print(m)
    #非貪婪
    #’?'取消任意次數貪婪匹配
    n=re.compile(r’a.
    ?b’)
    m=n.search(‘cdfadfdacvbdvd’) #儘可能少的匹配
    print(m)

    #’?‘取消至少一次的貪婪匹配
    n=re.compile(r’a.+?b’)
    m=n.search(‘cdfadfdacvbdvd’) #儘可能少的匹配
    print(m)

    #忽略大小寫re.I
    n=re.compile(r’hello’,‘hello world’,re.I)
    #正則是默認單行匹配,使用re.M可以進行多行匹配
    n=re.compile(r’hello’,‘hello\nworld’,re.M)

    #使’.‘匹配任意字符,re.s作爲單行處理,忽略\n
    string=’<div>hello</div>’

    n=re.compile(r’’)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章