目录
.* 和 .*? 有什么区别?
“.” 通配符
* 通配符匹配零个或多个字符
? 通配符匹配文件名中的 0 个或 1 个字符
表达式 .* 就是单个字符匹配任意次,即贪婪匹配。
表达式 .*? 是满足条件的情况只匹配一次,即最小匹配。
比如说匹配输入串B: 101000000000100
使用 1.*1 将会匹配到1010000000001, 匹配方法: 先匹配至输入串B的最后, 然后向前匹配, 直到可以匹配到1, 称之为贪婪匹配。
使用 1.?1 将会匹配到101, 匹配方法: 匹配下一个1之前的所有字符, 称之为懒惰匹配。
\s和\S
\s匹配任意的空bai白符(包括空格,du制表符(Tab),换行符,中文全角空格zhi)
\S则是任意不dao是空白符的字符
\w和\W
\w 等价于 [a-zA-Z0-9_]
\W 等价于 [^a-zA-Z0-9_],与\w相反的情况
正则表达式匹配字符串
1、re.search()用法
re.search()方法扫描整个字符串,并返回第一个成功的匹配。如果匹配失败,则返回None。
re.search(pattern, string, flags=0)
pattern : 正则中的模式字符串。
string : 要被查找替换的原始字符串。
flags : 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。
group() 会返回匹配此正则表达式的字符串
group(1) 会返回正则表达式中第一个括号内的内容, 以此类推,group(2) 第二个括号
例1
例2
import re
content = 'Hello 123456789 Word_This is just a test 666 Test'
result = re.search('(\d+).*?(\d+).*', content)
print(result)
print(result.group()) # 与 print(result.group(0)) 同样效果字符串
print(result.groups())
print(result.group(1))
print(result.group(2))
结果:
<_sre.SRE_Match object; span=(6, 49), match='123456789 Word_This is just a test 666 Test'>
123456789 Word_This is just a test 666 Test
('123456789', '666')
123456789
666
Process finished with exit code 0
flag用法:
import re
html='''<div id="songs-list">
<h2 class="title">经典老歌</h2>
<p class="introduction">
经典老歌列表
</p>
<ul id ="list" class="list-group">
<li data-view="2">一路上有你</li>
<li data-view="7">
<a href="/2.mp3" singer="任贤齐">沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月</a></li>
<li data-view="5"><a href="/5.mp3" singer="陈惠琳">记事本</a></li>
<li data-view="5">
<a href="/6.mp3" singer="邓丽君"><i class="fa fa-user"></i>但愿人长久</a>
</li>
</ul>
</div>
'''
result = re.search('<li.*?singer="(.*?)">(.*?)</a></li>', html)
if result:
print(result.group(1), result.group(2))
beyond 光辉岁月
result = re.search('<li.*?singer="(.*?)">(.*?)</a></li>', html, re.S) # re.S确保.能匹配到换行符
if result:
print(result.group(1), result.group(2))
任贤齐 沧海一声笑</a>
</li>
<li data-view="4" class="active">
<a href="/3.mp3" singer="齐秦">往事随风</a>
</li>
<li data-view="6"><a href="/4.mp3" singer="beyond">光辉岁月
2、match()方法
这个方法的用途是匹配字符串开头的字符,它从字符串的起始处开始匹配,匹配成功后立即返回Match对象,不匹配则返回None值,它的语法格式如下:
re.match(pattern,string,[flags])
方法名关键字match前一定要加上re模块名称,并使用“.”连接;
小括号内有三个参数使用逗号“,”分隔;
第一个参数就是正则表达式pattern(模板),属于必填参数;
第二个参数是要匹配的字符串string,也属于必填参数;
第三个参数是标志位,用来控制匹配的方式,属于可选参数,并且Python中的常用标志如下图所示:
3、findall()方法
这种方法的功能就比前两种要强大一些,它是匹配字符串中所有的合乎规则的字符,并将所有的匹配结果返回成为一个列表,匹配成功就返回一个有内容的列表,不成功则返回一个空列表。语法格式如下所示:
re.findall(pattern,string,[flags])
格式很雷同,参数用法也和前两种方法一样,直接上例子,详见下图:
search()和match()的区别 https://www.cnblogs.com/aaronthon/p/9435967.html
正则匹配电话号码
手机号-方法1
import re
# 正则匹配手机号
def judge_phone_number(account):
a = re.findall('(13\d{9}|14[5|7]\d{8}|15\d{9}|166{\d{8}|17[3|6|7]{\d{8}|18\d{9})', account)
print(a)
手机号-方法2
str="15838477645dfdfdf15887988765dfdf1157990087651fd157385367891fdf15826789876qqq15838545678a"
#方法一:限制手机号开头,或者手机号前面为非数字,且手机号结尾或者以非数字结尾
pattern1="(?:^|[^\d])(1\d{10})(?:$|[^\d])"
phone_list1=re.compile(pattern1).findall(str)
#结果为:['15838477645', '15887988765', '15826789876', '15838545678']
手机号-方法3
#方法二:利用负向零宽断言,断言手机号前后不能出现数字
pattern2="(?<!\d)(1\d{10})(?!\d)"
phone_list2=re.compile(pattern2).findall(str)
#结果为:['15838477645', '15887988765', '15826789876', '15838545678']
座机号的匹配:
- (?<!\d)表示负向后行零宽断言,该位置的前面不可以是数字。
- (?<!\d)......(?!\d)表示与该字符串的首尾相邻的字符均不能是数字
(?=\s)要求数字后面跟一个空格字符,所以如果数字位于字符串的末尾,则数字将不匹配
(?!\S),则负向预测将通过,因为字符串末尾的数字后面没有非空白字符。