全网最全python正则表达式详解

正则表达式是一种用于匹配、查找和操作文本的强大工具,可以用来识别符合特定模式的文本串。它是由一系列字符和特殊元字符组成的字符串,使用特定的语法规则来描述匹配的模式。正则表达式在各种编程语言和文本编辑器中都得到广泛支持,如Python、Java、C++、JavaScript等。正则表达式的应用场景非常广泛,包括但不限于以下方面:

图片

总而言之,正则表达式是一种强大的工具,用于处理和操作文本数据。通过灵活运用正则表达式,可以简化和优化文本处理的过程,提高效率和准确性。

图片

图片

图片

图片

图片

图片

ompile(pattern[,flags]):创建模式对象

search(pattern,string[,flags]):在整个字符串中寻找匹配模式
match(pattern,string[,flags]):从字符串的开始处匹配模式 
findall(pattern,string[,flags]):返回包含字符串中所有与模式匹配的项的列表
split(pattern,string[,maxsplit=0]):根据模式分割字符串
sub(pat,repl,string[,count=0]):字符串替换
escape(string):将字符串中所有特殊正则表达式字符转义
finditer(pattern,string,flags=0):返回包含所有匹配项的迭代对象,其中每个匹配项都是match对象
match(pattern,string[,flags]):从字符串的开始处匹配模式,返回match对象或none
subn(pat,repl,string[,count=0]): 返回新字符串与替换次数组成的元祖
参数flags值:
re.I:忽略大小写
re.L:支持本地字符集的字符
re.M:多行匹配模式
re.S:使用元字符.匹配任意字符,包括换行符
re.U:匹配unicode字符
re.X:忽略模式中的空格,并可以使用#注释的不同组合(使用|进行组合)
In [47]: import re
In [48]: test = '''
   ...: Hello welcome to my python regex!
   ...: Now is 2019-07-16 19:05:25
   ...: My name is yanjiaxi
   ...: My phone number is 0874-8452132
   ...: My email is xyyanjiaxi@163.com
   ...: I am studying python
   ...: '''
   
匹配以py开头的单词:
In [49]: r1 = re.compile(r'\bpy\w+\b',re.S)
In [50]: re1 = r1.findall(test)
In [51]: print(re1)
['python', 'python']

匹配以e结尾的单词:
In [79]: re2 = re.compile(r'\w+e\b')
In [80]: r2 = re2.findall(test)
In [81]: print(r2)
['welcome', 'name', 'phone']

匹配电话号码:
In [85]: re3 = re.compile(r'\d{4}-?\d{7}')
In [86]: r3 = re3.findall(test)
In [87]: print(r3)
['0874-8452132']

找出单词长度为6-8个字母长度:
In [102]: re4 = re.compile(r'\b[a-zA-Z]{6,8}\b')
In [103]: r4 = re4.findall(test)
In [104]: print(r4)
['welcome', 'python', 'yanjiaxi', 'number', 'studying', 'python']


match对象相关属性与方法
In [160]: date = "2019-07-16 19:05:25"
In [161]: re5 = re.match(r'(\d{4})-(\d{2})-(\d{2})\s?(\d\d)\:(\d\d)\:(\d\d)',date)
In [162]: print(re5.string)
2019-07-16 19:05:25  #打印匹配时使用的文本

In [163]: print(re5.re) #打印匹配模式
re.compile('(\\d{4})-(\\d{2})-(\\d{2})\\s?(\\d\\d)\\:(\\d\\d)\\:(\\d\\d)')

In [164]: print(re5.pos) #开始搜索索引
0

In [165]: print(re5.endpos) #结束时的索引
19

In [166]: print(re5.lastindex)#最后一个被捕获的分组在文本中的索引
6

In [167]: print(re5.lastgroup)#最后一个被捕获的分组的别名
None

In [168]: print(re5.group(0))#group(group1,..groupn)
2019-07-16 19:05:25#捕获一个或多个分组截获的字符串

In [169]: print(re5.group(1,2))
('2019', '07')

In [170]: print(re5.groups()) #返回全部的分组捕获的字符串
('2019', '07', '16', '19', '05', '25')

In [172]: print(re5.start(2))
5  #指定的组截获的子串在re5中的起始索引

In [173]: print(re5.end(2))
7 #指定的组截获的子串在re5中的结束索引

In [174]: print(re5.span(2))
(5, 7)  #返回start(group)和end(group)

返回一个可迭代对象
In [222]: itor = re.finditer(r'\w+',b)
In [223]: for i in itor:
    ...:     print(i.group())
    ...:
abc
def
ghi

#匹配163邮箱地址
In [9]: re6 = re.compile(r'\b\w+@\d{3}\.\w+\b')
In [10]: r6 = re6.findall(test)
In [12]: print(r6)
['xyyanjiaxi@163.com']

体会一下贪婪与非贪婪模式
In [13]: re7 = re.compile(r'\bn.+?\b')
In [14]: r7 = re7.findall(test)
In [15]: print(r7)
['name']
In [16]: re8 = re.compile(r'\bn.+\b')
In [17]: r8 = re8.findall(test)
In [18]: print(r8)
['name is yanjiaxi']
In [19]: re9 = re.compile(r'\bn.*\b')
In [20]: r9 = re9.findall(test)
In [21]: print(r9)
['name is yanjiaxi']
In [22]: re10 = re.compile(r'\bn.*?\b')
In [23]: r10 = re10.findall(test)
In [24]: print(r10)
['name']

找出含某个字母的单词(t)
In [29]: re11 = re.findall(r'\b\w*t\w*\b',test)
In [30]: print(re11)
['to', 'python', 'studying', 'python']

匹配指定字串单词
In [35]: re12 = re.findall(r'[m|M]y|python|email',test)
In [36]: print(re12)
['my', 'python', 'My', 'My', 'My', 'email', 'python']

分割split
In [41]: date = "2019-07-16 19:05:25"
In [42]: re13 = re.split(r'[-|:|\s]',date)
In [43]: print(re13)
['2019', '07', '16', '19', '05', '25']
指定分割次数
In [47]: date = "2019-07-16 19:05:25"
In [48]: re14 = re.split(r'[-|:|\s]',date,maxsplit = 3)
In [49]: print(re14)
['2019', '07', '16', '19:05:25']

字符串替换
In [51]: re15 = re.sub('python','cython',test)
In [52]: print(re15)
Hello welcome to my cython regex!
Now is 2019-07-16 19:05:25
My name is yanjiaxi
My phonenumber is 0874-8452132
My email is xyyanjiaxi@163.com
I am studying cython
返回新字符与替换次数的元祖
In [62]: re18 = re.subn('python','cython',test,count = 1)
In [63]: print(re18)
('\nHello welcome to my cython regex!\nNow is 2019-07-16 19:05:25\nMy name is yanjiaxi\nMy phonenumber is 0874-8452132\nMy email is xyyanjiaxi@163.com\nI am studying python\n', 1)

In [57]: re16 = re.sub('python','cython',test,count = 1)
In [58]: print(re16)
Hello welcome to my cython regex!
Now is 2019-07-16 19:05:25
My name is yanjiaxi
My phonenumber is 0874-8452132
My email is xyyanjiaxi@163.com
I am studying python

字符串特殊字符转义实现
In [59]: re17 = re.escape("http://www.baidu.com")
In [61]: re17
Out[61]: 'http://www\\.baidu\\.com'

子模式扩展语法
In [83]: re19 = re.match(r'(?P<course1>\b\w.+?\b)(?P<course2>\b\w.+?\b)',"Python Linux")
In [84]: re19.group('course1')
Out[84]: 'Python '

In [85]: re19.group('course2')
Out[85]: 'Linux'

In [86]: re19.groups()
Out[86]: ('Python ', 'Linux')

In [87]: re19.groupdict()
Out[87]: {'course1': 'Python ', 'course2': 'Linux'}

In [156]: test1 = "Welcome to my linux and python world.I like python"
In [157]: re20 = re.search(r'(?<=\w\s)python(?=\s\w)',test1)
In [158]: print(re20.span())
(24, 30)  #匹配中间单词

In [161]: re21 = re.search(r'(?:and\s)python(\sworld)',test1)
In [162]: print(re21.span())
(20, 36)
In [163]: re21 #查找前面是and的python world组合
Out[163]: <re.Match object; span=(20, 36), match='and python world'>
In [164]: re21.group(0)
Out[164]: 'and python world'
In [165]: re21.group(1)
Out[165]: ' world'

In [181]: re22 = re.findall(r'\b(?i)w\w+\b',test1)
In [182]: re22 #查找以w和W开头的单词
Out[182]: ['Welcome', 'world']

In [183]: re22 = re.search(r'\b(?<!and\s)python\b',test1)
In [184]: re22 #查找前面不是and的python
Out[184]: <re.Match object; span=(48, 54), match='python'>

通过索引后向引用实现交换
In [196]: s = re.sub(r'(\d{4})-(\d{7})',r'\2-\1',test)

In [197]: s
Out[197]: '\nHello welcome to my python regex!\nNow is 2019-07-16 19:05:25\nMy name is yanjiaxi\nMy phonenumber is 8452132-0874\nMy email is xyyanjiaxi@163.com\nI am studying python\n'


In [215]: a = "123.py"
In [216]: b = "demo.txt"
In [217]: re.findall(r'^.+?\..+?$(?<!txt$)',a)#提取不以.txt结尾的文件
Out[217]: ['123.py']

In [218]: re.findall(r'^(?!\d+).*',a)
Out[218]: []

In [219]: re.findall(r'^(?!\d+).*',b)#提取不以数字开头的文件
Out[219]: ['demo.txt']

In [220]: re.findall(r'^(?!\d+).+?\..*$(?<!py$)',b)#提取不以.py结尾的文件
Out[220]: ['demo.txt']

通过别名后向引用
In [209]: m = "i love my lover"
In [210]: n = re.search(r"\w\s(?P<name>(l..e)).+?(?P=name)\w",m)
In [211]: n.groups()
Out[211]: ('love', 'love')

In [212]: n.group(1)
Out[212]: 'love'

In [213]: n.group(2)
Out[213]: 'love'

此为豆瓣电影信息的简单爬取,体会正则在数据挖掘中的应用
import requests
import re
url = "http://maoyan.com/board/4?offset=3"
response = requests.get(url)
print (response.text)
s = re.findall('<dd>.*?board-index.*?>(\d+)</i>.*?data-src="(.*?)".*?name"><a'+'.*?>(.*?)</a>.*?star">(.*?)</p>.*?releasetime">(.*?)</p>'+'.*?integer">(.*?)</i>.*?fraction">(.*?)</i>.*?</dd>',response.text,re.S)
##print(s)
m = [(i[0],i[1],i[2],i[3].strip()[3:],i[4].strip()[5:],i[5] + i[6]) for i in s]
print(m)

[('4', 'https://p1.meituan.net/movie/6bea9af4524dfbd0b668eaa7e187c3df767253.jpg@160w_220h_1e_1c', '这个杀手不太冷', '让·雷诺,加里·奥德曼,娜塔莉·波特曼', '1994-09-14(法国)', '9.5'),
('5', 'https://p1.meituan.net/movie/b607fba7513e7f15eab170aac1e1400d878112.jpg@160w_220h_1e_1c', '泰坦尼克号', '莱昂纳多·迪卡普里奥,凯特·温丝莱特,比利·赞恩', '1998-04-03', '9.5'),
('6', 'https://p0.meituan.net/movie/da64660f82b98cdc1b8a3804e69609e041108.jpg@160w_220h_1e_1c', '唐伯虎点秋香', '周星驰,巩俐,郑佩佩', '1993-07-01(中国香港)', '9.1'),
('7', 'https://p0.meituan.net/movie/46c29a8b8d8424bdda7715e6fd779c66235684.jpg@160w_220h_1e_1c', '魂断蓝桥', '费雯·丽,罗伯特·泰勒,露塞尔·沃特森', '1940-05-17(美国)', '9.2'),
('8', 'https://p0.meituan.net/movie/223c3e186db3ab4ea3bb14508c709400427933.jpg@160w_220h_1e_1c', '乱世佳人', '费雯·丽,克拉克·盖博,奥利维娅·德哈维兰', '1939-12-15(美国)', '9.1'),
('9', 'https://p1.meituan.net/movie/ba1ed511668402605ed369350ab779d6319397.jpg@160w_220h_1e_1c', '天空之城', '寺田农,鹫尾真知子,龟山助清', '1992', '9.1'),
('10', 'https://p0.meituan.net/movie/b0d986a8bf89278afbb19f6abaef70f31206570.jpg@160w_220h_1e_1c', '辛德勒的名单', '连姆·尼森,拉尔夫·费因斯,本·金斯利', '1993-12-15(美国)', '9.2'),
('11', 'https://p1.meituan.net/movie/18e3191039d5e71562477659301f04aa61905.jpg@160w_220h_1e_1c', '喜剧之王', '周星驰,莫文蔚,张柏芝', '1999-02-13(中国香港)', '9.1'),
('12', 'https://p1.meituan.net/movie/14a7b337e8063e3ce05a5993ed80176b74208.jpg@160w_220h_1e_1c', '大闹天宫', '邱岳峰,毕克,富润生', '1965-12-31', '9.0'),
('13', 'https://p1.meituan.net/movie/6bc004d57358ee6875faa5e9a1239140128550.jpg@160w_220h_1e_1c', '音乐之声', '朱莉·安德鲁斯,克里斯托弗·普卢默,埃琳诺·帕克', '1965-03-02(美国)', '9.0')]

import re 
pattern_0 = re.compile(r'(.*?(省|自治区|特别行政区|市))')
pattern_1 = re.compile(r'(.*?(?:省|自治区|特别行政区|市))')
s = '云南省曲靖市'
result_0 = re.search(pattern_0, s).groups()
result_1 = re.search(pattern_1, s).groups()
result_0 #('云南省', '省')
result_1 #('云南省',)

在Python的正则表达式中,可以使用一些标志来修改匹配的行为。这些标志可以通过在正则表达式的模式字符串中使用特定字符来指定。

(?iLmsux)是用于指定标志的语法,它可以在正则表达式模式字符串的开始位置使用。

以下是这些标志的含义:

  • i:忽略大小写匹配。

  • L:启用特定区域设置(locale)的字母匹配,以进行本地化匹配。

  • m:多行模式,使得元字符^匹配字符串的开头和每行的开头,以及元字符$匹配字符串的末尾和每行的末尾。

  • s:使元字符.匹配包括换行符在内的任意字符。

  • u:启用Unicode模式,将模式和被匹配的字符串都视为Unicode字符序列。

  • x:启用扩展模式,使得正则表达式可以包含空格和注释。空格字符在模式中将被忽略,除非它们被转义,或者位于字符类中。

    import re
    
    text = "Hello World\nhello\nI like Python"
    
    # 使用(?im)标志启用忽略大小写和多行模式
    pattern = r"(?im)hello"
    result = re.findall(pattern, text)
    print(result)  # 输出: ['Hello']
    
    # 使用(?is)标志启用忽略大小写和使.匹配任意字符(包括换行符)
    pattern = r"(?is)hello.*python"
    result = re.findall(pattern, text)
    print(result)  # 输出: ['Hello World\nI am Python']
    (?#...)是正则表达式中的注释语法,它可以用来添加对模式的描述,提高代码的可读性。具体来说,(?#...)表示一个非捕获组(Non-capturing group),也就是匹配括号中的内容但不进行捕获。
    
    import re
    
    # 匹配日期,格式为YYYY-MM-DD
    pattern = r"(?#年份)\d{4}-(?#月份)\d{2}-(?#日期)\d{2}"
    
    # 测试字符串
    text = "今天的日期是2022-07-08"
    
    # 使用re模块的findall函数进行匹配
    matches = re.findall(pattern, text)
    
    print(matches) #['2022-07-08']
    
    
    import re
    
    # 匹配日期,格式为YYYY-MM-DD
    pattern = r"(?#年份)\d{4}-(?#月份)\d{2}-(?#日期)\d{2}"
    
    # 测试字符串
    text = "今天的日期是2022-07-08"
    
    # 使用re模块的findall函数进行匹配
    matches = re.findall(pattern, text)
    
    print(matches) #['2022-07-08']
    
    import re
    
    # 匹配包含"apple"后面紧跟着"pie"的字符串
    pattern = r"like (.*?)(?= pie)"
    
    # 测试字符串
    text = "I like apple pie"
    
    # 使用re模块的findall函数进行匹配
    matches = re.findall(pattern, text)
    
    print(matches) #['apple']
    
    import re
    
    # 匹配不包含"apple"后面紧跟着"pie"的字符串
    pattern = r"apple(?!pie)"
    
    # 测试字符串
    text = "I like apple crisp"
    
    # 使用re模块的findall函数进行匹配
    matches = re.findall(pattern, text)
    
    print(matches)
    
    
    import re
    
    # 匹配前面紧跟着"apple"的数字
    pattern = r"(?<=apple)\d+"
    
    # 测试字符串
    text = "I have 3 apples and 2 pears"
    
    # 使用re模块的findall函数进行匹配
    matches = re.findall(pattern, text)
    
    print(matches) #['3']
    #正则表达式的正向后查找语法(?<=...)来匹配前面紧跟着"apple"的数字。具体来说,(?<=apple)表示该位#置前面紧跟着"apple";\d+表示匹配一个或多个数字。因此,正向后查找会匹配到"3"这个数字。
    
    
    
    import re
    
    # 匹配 AABB、ABAB 等格式的四字成语
    pattern = r'(((.).\3.)|((.)\5(.)\6))'
    
    # 测试字符串
    text = "ABCD EFGH IIJJ KLMN OPOP QRST UVWX YYZZ ABAC"
    
    # 使用 re 模块的 findall 函数进行匹配
    matches = re.findall(pattern, text)
    
    print("匹配ABAC、ABAB、AABB的词语:", list(i[0] for i in findall(pattern, text)))
    #匹配ABAC、ABAB、AABB的词语:['IIJJ', 'OPOP', 'YYZZ', 'ABAC']

    3、总结

    本文,我们极尽详细地介绍python正则表达式的使用场景及使用方式。掌握正则,轻松应对各种场景的字符和文本处理。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值