设为首页收藏本站

Crossin的编程教室

 找回密码
 立即加入
查看: 38344|回复: 10
打印 上一主题 下一主题

【Python 第57课】 正则表达式(3)

[复制链接]

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

跳转到指定楼层
楼主
发表于 2013-9-22 16:51:05 |显示全部楼层 |倒序浏览

先来公布上一课习题的答案:


\bs\S*?e\b


有的同学给出的答案是"\bs.*?e\b"。测试一下就会发现,有奇怪的'sea sue'和'sweet see'混进来了。既然是单词,我们就不要空格,所以需要用"\S"而不是"."


昨天有位同学在论坛上说,用正则表达式匹配出了文件中的手机号。这样现学现用很不错。匹配的规则是"1.*?\n",在这个文件的条件下,是可行的。但这规则不够严格,且依赖于手机号结尾有换行符。今天我来讲讲其他的方法。


匹配手机号,其实就是找出一串连续的数字。更进一步,是11位,以1开头的数字。


还记得正则第1讲里提到的[]符号吗?它表示其中任意一个字符。所以要匹配数字,我们可以用

[0123456789]


由于它们是连续的字符,有一种简化的写法:[0-9]。类似的还有[a-zA-Z]的用法。


还有另一种表示数字的方法:

\d


要表示任意长度的数字,就可以用

[0-9]*

或者

\d*


但要注意的是,*表示的任意长度包括0,也就是没有数字的空字符也会被匹配出来。一个与*类似的符号+,表示的则是1个或更长。


所以要匹配出所有的数字串,应当用

[0-9]+

或者

\d+


如果要限定长度,就用{}代替+,大括号里写上你想要的长度。比如11位的数字:

\d{11}


想要再把第一位限定为1,就在前面加上1,后面去掉一位:

1\d{10}


OK. 总结一下今天提到的符号:

[0-9]

\d

+

{}


现在你可以去一个混杂着各种数据的文件里,抓出里面的手机号,或是其他你感兴趣的数字了。


#==== Crossin的编程教室 ====#
微信ID:crossincode
论坛:http://crossin.me
QQ群:156630350

面向零基础初学者的编程课
每天5分钟,轻松学编程


#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

沙发
发表于 2013-9-27 13:25:51 |显示全部楼层
simple 发表于 2013-9-27 09:11
mport re
text = 'site sea sue sweet see case sse ssee loses'
pattern = re.compile(r'\bs\S*?e\b')

compile会把正则表达式编译成一个对象,据说效率上会高一些,尤其在使用同一个规则多次匹配的时候
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

板凳
发表于 2014-6-22 23:15:55 |显示全部楼层
paul 发表于 2014-6-22 20:28
请教一下,我为什么一用\b,运行结果就会是not match?
import re
#text="Hi,I am Shirley Hilton,I am his  ...

字符里的\会被转义。\b是有另有含义。所以要么用\\b,(用\\转义成为\)。要么用r"\b"替代"\b",带前缀r的字符串表示raw,对其中的字符不转义
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

地板
发表于 2014-6-24 19:03:10 |显示全部楼层
paul 发表于 2014-6-23 21:57
再问一个问题:前题答案用\bs\S*e\b,是不是也可以?

但如果有sxxxe这种就不行了
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

5#
发表于 2014-6-25 10:32:53 |显示全部楼层
paul 发表于 2014-6-24 22:09
可以啊,为什么我也能匹配出来?
还有多一个?有什么区别吗?
?表示0个或1个,*表示0个或多个,两者放一 ...

不好意思,看错了。的确是可以的,不需要有?
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

6#
发表于 2016-1-8 10:36:04 |显示全部楼层
周末晒被子 发表于 2016-1-7 23:08
先生,这样的代码:其运行结果是这样:['site sea sue sweet see case sse ssee loses', ''],不明白的是, ...

因为空字符也是满足.*这个条件的
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

7#
发表于 2016-1-9 21:03:36 |显示全部楼层
周末晒被子 发表于 2016-1-8 12:28
1,可是 'site sea sue sweet see case sse ssee loses' 这个字符串已经把 text 的从头到尾,所有的位置 ...

结尾的。开头开始因为优先匹配最长的,已经匹配掉了
空字符不占位置
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

8#
发表于 2016-11-16 15:08:24 |显示全部楼层
yunzhou 发表于 2016-11-15 19:41
import re
text = "12222222222,14444444444,15555555555,16666666666666,0111111111111,125465245625"
m = ...

它匹配了其中的12位啊,你数数看输出的位数(用这种测试用例很容易看花眼的……)

你如果是要判断一整段正好12位的数字,应该前后加上 \b
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

9#
发表于 2018-7-28 01:03:30 |显示全部楼层
shan91 发表于 2018-7-27 15:35
老师,条件都放这么宽松了,为什么一个数字都搜索不出来~~

你的text是 ‘b’ 这个字符啊……

你直接用b这个变量就好了,何必多此一举,还弄错了
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

174

主题

45

好友

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

10#
发表于 2019-6-5 14:04:18 |显示全部楼层
pigcare 发表于 2019-6-5 10:54
请教一个问题,问什么我用Pyhton3,识别不了\b、\d呢,IDE是Pycharm,代码如下:
import re
print(re.finda ...

规则前面要加 r,避免字符串转义
r"\bs*e\b"
#==== Crossin的编程教室 ====#
微信ID:crossincode
网站:http://crossincode.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即加入

QQ|手机版|Archiver|Crossin的编程教室 ( 苏ICP备15063769号  

GMT+8, 2024-5-3 15:17 , Processed in 0.029044 second(s), 25 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部