正则表达式(面试会考)

简介: 正则表达式(面试会考)

在Python中需要通过正则表达式对字符串进行匹配的时候,可以使用一个模块,名字为re。


1.re模块操作


1.1 re模块的使用过程

# 导入re模块
import re
# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)
# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()

1.2 re模块示例

In [1]: import re
In [2]: # re.match(正则表达式, 需要处理的字符串)
In [3]: re.match(r"hello", "hello world")
#有返回值,用户的数据符合规范
Out[3]: <_sre.SRE_Match object; span=(0, 5), match='hello'>
#无返回值,用户的数据符合规范
In [4]: re.match(r"hello", "Hello world")
In [5]: re.match(r"[hH]ello", "Hello world")
Out[5]: <_sre.SRE_Match object; span=(0, 5), match='Hello'>
In [6]: re.match(r"[hH]ello", "hello world")
Out[6]: <_sre.SRE_Match object; span=(0, 5), match='hello'>

1.3 说明


re.match() 能够匹配出以xxx开头的字符串


2.匹配单个字符


20191228191448265.png

2.1 \d

In [8]: re.match(r"速度与激情1", "速度与激情2")  #无返回值
In [11]: re.match(r"速度与激情\d", "速度与激情5")
Out[11]: <_sre.SRE_Match object; span=(0, 6), match='速度与激情5'>
In [12]: ret = re.match(r"速度与激情\d", "速度与激情5")
In [13]: ret.group()
Out[13]: '速度与激情5'
In [16]: ret = re.match(r"速度与激情\d", "速度与激情55") #\d只能代表一位数字
In [17]: ret.group()
Out[17]: '速度与激情5'

2.2 [ ]

In [22]: ret = re.match(r"速度与激情[12345678]", "速度与激情1")
In [23]: ret.group()
Out[23]: '速度与激情1'
In [24]: re.match(r"速度与激情[12345678]", "速度与激情1").group()
Out[24]: '速度与激情1'
In [30]: re.match(r"速度与激情[1-8]", "速度与激情3")
Out[30]: <_sre.SRE_Match object; span=(0, 6), match='速度与激情3'>
#中间数字不连续
In [40]: re.match(r"速度与激情[123678]", "速度与激情8")
Out[40]: <_sre.SRE_Match object; span=(0, 6), match='速度与激情8'>
In [42]: re.match(r"速度与激情[1-36-8]", "速度与激情1")
Out[42]: <_sre.SRE_Match object; span=(0, 6), match='速度与激情1'>

2.3 \w


In [65]: re.match(r"速度与激情\w", "速度与激情哈").group()
Out[65]: '速度与激情哈'


2.4 \s

In [67]: re.match(r"速度与激情\s\d", "速度与激情 1").group()
Out[67]: '速度与激情 1'
In [68]: re.match(r"速度与激情\s\d", "速度与激情\t1").group()
Out[68]: '速度与激情\t1'

2.5 .


In [75]: re.match(r"速度与激情.", "速度与激情#").group()
Out[75]: '速度与激情#'


3.匹配多个字符


20191228192601342.png


3.1 {}

In [81]: re.match(r"速度与激情\d{1,3}", "速度与激情12").group()
Out[81]: '速度与激情12'
In [82]: re.match(r"速度与激情\d{1,3}", "速度与激情123").group()
Out[82]: '速度与激情123'
如果{}里面只有一位数字,则{}前面指定的是什么,必须有多少位
In [88]: re.match(r"\d{11}", "123456A78901").group()
AttributeError: 'NoneType' object has no attribute 'group'

3.2 ?


In [91]: re.match(r"021-?\d{8}", "021-12345678").group()
Out[91]: '021-12345678'
In [97]: re.match(r"\d{3,4}-?\d{7,8}", "0532-1234567").group()
Out[97]: '0532-1234567'

3.3 *

三个双引号之间的内容可以换行
In [98]: html_content = """fdsf
    ...: kasdjfkjasdkfjkasdjfjahsdufhawufhausdhfuahsdf
    ...: asdjfhjjasdhf"""
In [99]: print(html_content)
fdsf
kasdjfkjasdkfjkasdjfjahsdufhawufhausdhfuahsdf
asdjfhjjasdhf
In [100]: re.match(r".*", html_content).group()
Out[100]: 'fdsf'
In [101]: re.match(r".*", html_content, re.S).group()
Out[101]:"fdsf\nkasdjfkjasdkfjkasdjfjahsdufhawufhausdhfuahsdf\nasdjfhjjasdhf"
In [102]: re.match(r".*", "a").group()
Out[102]: 'a'
In [103]: re.match(r".*", "a1").group()
Out[103]: 'a1'
In [104]: re.match(r".*", "").group()
Out[104]: ''
In [105]: re.match(r".+", "a").group()
Out[105]: 'a'
In [106]: re.match(r".+", "ab").group()
Out[106]: 'ab'
In [107]: re.match(r".+", "abaksdjfkjasdkfjaksdjfkajsdfkjs").group()
Out[107]: 'abaksdjfkjasdkfjaksdjfkajsdfkjs'
In [108]: re.match(r".+", "").group()
AttributeError: 'NoneType' object has no attribute 'group'

4.匹配开头结尾


20191228193201252.png


4.1 例子:判断变量名是否符合要求

def main():
   names = ["age", "_age", "1age", "age1", "a_age", "age_1_", "age!", "a#123", "__________"]
   for name in names:
     # ret = re.match(r"[a-zA-Z_][a-zA-Z0-9_]*", name)
      # ^规定开头  $规定结尾  
      # python中的match默认是从头开始判断的所以,在match中可以不写^,但是match不会判断结尾,所以 # 当需要以xxx结尾的时候,还需要写上$
      ret = re.match(r"^[a-zA-Z_][a-zA-Z0-9_]*$", name)
      if ret:
         print("变量名:%s 符合要求....通过正则匹配出来的数据是:%s" % (name, ret.group()))
      else:
         print("变量名:%s 不符合要求...." % name)
if __name__ == "__main__":
   main()

4.2 例子:匹配163邮箱地址


import re
def main():
   email = input("请输入一个邮箱地址:")
   # 如果在正则表达式中需要用到了某些普通的字符,比如 . 比如? 等,仅仅需要在他们前面添加一个 反斜杠\进行转义
   ret = re.match(r"[a-zA-Z_0-9]{4,20}@163\.com$", email)
   if ret:
      print("%s符合要求...." % email)
   else:
      print("%s不符合要求...." % email)
if __name__ == "__main__":
   main()

5.匹配分组


20191228195931311.png20191228195931311.png

在正则表达式匹配正确的前提下,想要单独取出某一部分数据来,那么把那一部分的数据两边加上()
>>> import re
>>> re.match(r"[a-zA-Z0-9_]{4,20}@163\.com$", "laowang@163.com").group()
'laowang@163.com'

5.1 |


>>> import re
>>> re.match(r"[a-zA-Z0-9_]{4,20}@(163|126)\.com$", "laowang@126.com").group()
'laowang@126.com'


5.2 ()

在正则表达式匹配正确的前提下,想要单独取出某一部分数据来,那么把那一部分的数据两边加上()
>>> import re
>>> re.match(r"[a-zA-Z0-9_]{4,20}@(163|126)\.com$", "laowang@163.com").group(1)
'163'
>>> import re
>>> re.match(r"([a-zA-Z0-9_]{4,20})@(163|126)\.com$", "laowang@163.com").group(1)
'laowang'
>>> import re
>>> html_str = "<h1>hahahah</h1>"
>>> re.match(r"<(\w*)>.*</\1>", html_str).group()
'<h1>hahahah</h1>'
>>> import re
>>> html_str = "<body><h1>hahahah</h1></body>"
>>> re.match(r"<(\w*)><(\w*)>.*</\2></\1>", html_str).group()
'<body><h1>hahahah</h1></body>'

5.3 (?P)


>>> import re
>>> re.match(r"<(?P<p1>\w*)><(?P<p2>\w*)>.*</(?P=p2)></(?P=p1)>", html_str).group()
'<body><h1>hahahah</h1></body>'


2019122820015212.png


6.re模块的高级用法(python里面独有的)


Match()的功能是从头开始匹配,是其它语言都有的功能。


6.1 search


# 需求:匹配出文章阅读的次数
import re
ret = re.search(r"\d+", "阅读次数为 9999")
ret.group()
# 运行结果:
'9999'

6.2 findall

# 需求:统计出python、c、c++相应文章阅读的次数
import re
ret = re.findall(r"\d+", "python = 9999, c = 7890, c++ = 12345")
print(ret)
# 运行结果:
['9999', '7890', '12345']

6.3 sub 将匹配到的数据进行替换

# 需求:将匹配到的阅读次数加1
# 方法1:
import re
ret = re.sub(r"\d+", '998', "python = 997")
print(ret)
# 运行结果:
python = 998
import re
def add(temp):
    strNum = temp.group()
    num = int(strNum) + 1
    return str(num)
ret = re.sub(r"\d+", add, "python = 997")
print(ret)
ret = re.sub(r"\d+", add, "python = 99")
print(ret)
# 运行结果:
python = 998
python = 100

6.4 split 根据匹配进行切割字符串,并返回一个列表

# 需求:切割字符串“info:xiaoZhang 33 shandong”
# 要么冒号:要么空格切割
import re
ret = re.split(r":| ","info:xiaoZhang 33 shandong")
print(ret)
# 运行结果:
['info', 'xiaoZhang', '33', 'shandong']


20191228200820591.png

import re
test_str="""<dd class="job_bt">
        <h3 class="description">职位描述:</h3>
        <div class="job-detail" deep="4">
        <p>我们希望遇到以下的您:</p>
<p>1、负责监控平台整体架构的设计与开发;</p>
<p>2、负责完成音视频、服务端的开发,完成系统框架与核心代码的实现与日常维护;</p>
<p>3、负责设计和开发音视频编码、实时传输、存储以及播放解决方案;</p>
<p>4、负责技术攻关和创新技术引用,管理整体核心技术,组织制定和实施重大技术决策和技术方案,把握技术路线及技术发展方向,制定技术发展规划。</p>
<p><br data-filtered="filtered"></p>
<p>我们希望您具备以下能力:</p>
<p>1、计算机相关专业,本科及以上学历,2年以上多媒体相关开发经验;</p>
<p>2、熟悉常用算法和数据结构,有一定的架构能力和良好代码规范;</p>
<p>3、熟悉音视频编解码技术H264、hevc、amr、aac、音视频封装格式mp4、flv、mkv、mp3,熟悉常用开源库ffmpeg、srs、x264、libav;</p>
<p>4、精通TCP、UDP等网络传输协议和互联网视频的直播及点播应用开发,熟悉RTP/RTCP/RTSP/RTMP/HLS 等流媒体协议;</p>
<p><br data-filtered="filtered"></p>
<p>5、具有较高的职业素养、敬业精神具有极强的内驱力与责任心,能够承担较大的工作压力;</p>
<p>6、具有优秀的管理才能和职业操守,优秀的沟通能力和领导能力,工作风格干净利落,具有战略思维和团队激励能力,有较强的执行力。</p>
        </div>
    </dd>"""
ret=re.sub(r"<[^>]*>|&nbsp;|\n", "", test_str)
print(ret)
# 参考答案:
re.sub(r"<[^>]*>|&nbsp;|\n", "", test_str)


7.Python贪婪和非贪婪


Python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。


在"*","?","+","{m,n}"后面加上?,使贪婪变成非贪婪

>>> s="This is a number 234-235-22-423"
>>> r=re.match(".+(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'4-235-22-423'
>>> r=re.match(".+?(\d+-\d+-\d+-\d+)",s)
>>> r.group(1)
'234-235-22-423'


正则表达式模式中使用到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满足匹配最长字符串,在我们上面的例子里面,“.+”会从字符串的起始处抓取满足模式的最长字符,其中包括我们想得到的第一个整型字段中的大部分,“\d+”只需一位字符就可以匹配,所以它匹配了数字“4”,而“.+”则匹配了从字符串起始到这个第一位数字4之前的所有字符。


解决方式:非贪婪操作符“?”,这个操作符可以用在"*" “+” "?"的后面,要求正则匹配的越少越好。


>>> re.match(r"aa(\d+)","aa2343ddd").group(1)
'2343'
>>> re.match(r"aa(\d+?)","aa2343ddd").group(1)
'2'
>>> re.match(r"aa(\d+)ddd","aa2343ddd").group(1) 
'2343'
>>> re.match(r"aa(\d+?)ddd","aa2343ddd").group(1)
'2343'

练一练:请提取url地址


字符串为:

<img data-original="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" src="https://rpic.douyucdn.cn/appCovers/2016/11/13/1213973_201611131917_small.jpg" style="display: inline;">
参考答案
re.search(r"https://.*?\.jpg", test_str)

8. r的作用

>>> mm = "c:\\a\\b\\c"
>>> mm
'c:\\a\\b\\c'
>>> print(mm)
c:\a\b\c
>>> re.match("c:\\\\",mm).group()
'c:\\'
>>> ret = re.match("c:\\\\",mm).group()
>>> print(ret)
c:\
>>> ret = re.match("c:\\\\a",mm).group()
>>> print(ret)
c:\a
>>> ret = re.match(r"c:\\a",mm).group()
>>> print(ret)
c:\a
>>> ret = re.match(r"c:\a",mm).group()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'group'


说明:


Python中字符串前面加上 r 表示原生字符串,


与大多数编程语言相同,正则表达式里使用 " \ " 作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符 " \ ",那么使用编程语言表示的正则表达式里将需要4个反斜杠 " \ \ ":前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。


Python里的原生字符串很好地解决了这个问题,有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。


>>> ret = re.match(r"c:\\a",mm).group()
>>> print(ret)
c:\a
目录
相关文章
|
2月前
|
数据采集 Python
python中的正则表达式,Python实习面试经验汇总
python中的正则表达式,Python实习面试经验汇总
|
2月前
|
Python
Python正则表达式:面试中的难点与解题思路
【4月更文挑战第15天】本文聚焦Python正则表达式在面试中的难点,包括匹配模式与分组、重复匹配与量词、零宽断言与环视。通过实例解析常见面试题,如提取电子邮件域名、匹配连续重复单词和HTML标签间文本,强调了正则表达式的灵活性和易错点。学习正则表达式的基本语法、量词及高级特性,能帮助你在面试中应对文本处理问题。
32 1
|
2月前
|
Python
Python 内置正则表达式库re的使用
正则表达式是记录文本规则的代码,用于查找和处理符合特定规则的字符串。在Python中,常通过原生字符串`r&#39;string&#39;`表示。使用`re.compile()`创建正则对象,便于多次使用。匹配字符串有`match()`(从开头匹配)、`search()`(搜索首个匹配)和`findall()`(找所有匹配)。替换字符串用`sub()`,分割字符串则用`split()`。
45 3
|
1月前
|
数据库 Python
Python网络数据抓取(8):正则表达式
Python网络数据抓取(8):正则表达式
20 2
|
1月前
|
自然语言处理 JavaScript 前端开发
Python高级语法与正则表达式(二)
正则表达式描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
|
1月前
|
安全 算法 Python
Python高级语法与正则表达式(一)
Python提供了 with 语句的写法,既简单又安全。 文件操作的时候使用with语句可以自动调用关闭文件操作,即使出现异常也会自动关闭文件操作。
|
1月前
|
Python
Python使用正则表达式分割字符串
在Python中,你可以使用re模块的split()函数来根据正则表达式分割字符串。这个函数的工作原理类似于Python内置的str.split()方法,但它允许你使用正则表达式作为分隔符。
|
1月前
|
Python
Python中re模块的正则表达式
【6月更文挑战第2天】了解Python的re模块,它是处理正则表达式的核心工具。正则表达式用于在文本中查找特定模式。本文讨论了re模块的用法和技巧,包括导入模块、匹配、分组、替换文本、编译正则表达式以及使用预定义字符类、量词、锚点等高级功能。通过实例展示了如何在Python中执行这些操作,帮助提升文本处理能力。掌握这些技巧将使你更有效地利用正则表达式解决字符串处理问题。
21 2
|
26天前
|
Python
Python正则表达式详解:掌握文本匹配的魔法
Python正则表达式详解:掌握文本匹配的魔法
|
26天前
|
Python
python re 正则表达式库的使用
python re 正则表达式库的使用
15 0

热门文章

最新文章