Crossin的编程教室

标题: 【Python 第57课】 正则表达式(3) [打印本页]

作者: crossin先生    时间: 2013-9-22 16:51
标题: 【Python 第57课】 正则表达式(3)

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


\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分钟,轻松学编程



作者: eep    时间: 2013-9-23 15:29
沙发
作者: fl0w    时间: 2013-9-25 14:47
靠前
作者: 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')
m = pattern.findall(text)
print m

为什么说上面这段代码就比下面的效率高啊



import re
text = 'site sea sue sweet see case sse ssee loses'
m = re.findall(r'\bs\S*?e\b',text)
print m
作者: crossin先生    时间: 2013-9-27 13:25
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会把正则表达式编译成一个对象,据说效率上会高一些,尤其在使用同一个规则多次匹配的时候
作者: michael    时间: 2013-10-2 00:30
compile会把正则表达式编译成一个对象,据说效率上会高一些,尤其在使用同一个规则多次匹配的时候
作者: paul    时间: 2014-6-22 20:28
请教一下,我为什么一用\b,运行结果就会是not match?
import re
#text="Hi,I am Shirley Hilton,I am his wife."
text="site sea sue sweet see case sse ssee loses"
m=re.findall("\bs\S*?e\b",text)

if m:
    print m
else:
    print "not match"

代码如上,只要不用"\b",都是可以正常运行的,麻烦懂的解释一下吧

作者: crossin先生    时间: 2014-6-22 23:15
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,对其中的字符不转义
作者: paul    时间: 2014-6-23 18:06
crossin先生 发表于 2014-6-22 23:15
字符里的\会被转义。\b是有另有含义。所以要么用\\b,(用\\转义成为\)。要么用r"\b"替代"\b",带前缀r ...

好的,谢谢,解决了!
作者: paul    时间: 2014-6-23 21:57
再问一个问题:前题答案用\bs\S*e\b,是不是也可以?
作者: crossin先生    时间: 2014-6-24 19:03
paul 发表于 2014-6-23 21:57
再问一个问题:前题答案用\bs\S*e\b,是不是也可以?

但如果有sxxxe这种就不行了
作者: paul    时间: 2014-6-24 22:09
crossin先生 发表于 2014-6-24 19:03
但如果有sxxxe这种就不行了

可以啊,为什么我也能匹配出来?
还有多一个?有什么区别吗?
?表示0个或1个,*表示0个或多个,两者放一块不还是0个或多个吗?
作者: crossin先生    时间: 2014-6-25 10:32
paul 发表于 2014-6-24 22:09
可以啊,为什么我也能匹配出来?
还有多一个?有什么区别吗?
?表示0个或1个,*表示0个或多个,两者放一 ...

不好意思,看错了。的确是可以的,不需要有?
作者: liu-pengfei    时间: 2014-9-28 23:36
看到这里,上节课的问题解决了。又学习了新知识。
作者: liu-pengfei    时间: 2014-9-28 23:37
paul 发表于 2014-6-23 21:57
再问一个问题:前题答案用\bs\S*e\b,是不是也可以?

是可以的。但是我这样\bs.*?e\b是不可以的。
作者: 周末晒被子    时间: 2016-1-7 23:08
先生,这样的代码:
  1. import re
  2. text = "site sea sue sweet see case sse ssee loses"
  3. m = re.findall(r".*", text)
  4. if m:
  5.     print m
  6. else:
  7.     print 'not match'
复制代码
其运行结果是这样:['site sea sue sweet see case sse ssee loses', ''],不明白的是,list里面两个字符串的后面那个空字符串哪里来的?
作者: crossin先生    时间: 2016-1-8 10:36
周末晒被子 发表于 2016-1-7 23:08
先生,这样的代码:其运行结果是这样:['site sea sue sweet see case sse ssee loses', ''],不明白的是, ...

因为空字符也是满足.*这个条件的
作者: 周末晒被子    时间: 2016-1-8 12:28
crossin先生 发表于 2016-1-8 10:36
因为空字符也是满足.*这个条件的

1,可是 'site sea sue sweet see case sse ssee loses' 这个字符串已经把 text 的从头到尾,所有的位置表达完了,都没有更多一个位置来给 "." 安放了,这个空字符串在哪里?

2,而且如果末尾有一个空字符串,那么开头也应该有吧,可是开头并没有。
作者: crossin先生    时间: 2016-1-9 21:03
周末晒被子 发表于 2016-1-8 12:28
1,可是 'site sea sue sweet see case sse ssee loses' 这个字符串已经把 text 的从头到尾,所有的位置 ...

结尾的。开头开始因为优先匹配最长的,已经匹配掉了
空字符不占位置
作者: catherinemic    时间: 2016-2-2 15:56
打卡~~
作者: xqqxjnt1988    时间: 2016-2-4 14:21
来交这堂课的作业啦
m = re.findall(r'1\d{10}',text2)            #匹配手机号是不是这样写的,crossing先生
作者: yunzhou    时间: 2016-11-15 19:41
本帖最后由 yunzhou 于 2016-11-15 19:44 编辑

import re
text = "12222222222,14444444444,15555555555,16666666666666,0111111111111,125465245625"
m = re.findall(r"\d{12}",text)
if m:
    print m
else:
    print 'not match'


为什么大于12位的都要输出呢,不是应该只输出12位的吗?
请问哪里错了呢?
而且如果m = re.findall(r"1\d{12}",text)
只会输出一个14位的16这一串数字
作者: crossin先生    时间: 2016-11-16 15:08
yunzhou 发表于 2016-11-15 19:41
import re
text = "12222222222,14444444444,15555555555,16666666666666,0111111111111,125465245625"
m = ...

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

你如果是要判断一整段正好12位的数字,应该前后加上 \b
作者: 海浪的风    时间: 2016-12-2 19:57
assafasf
作者: l0ve1o24    时间: 2017-1-13 16:58
import re
f = open('shouji.txt')
s = f.read()
print s
m = re.findall(r'1\d{10}',s)
for i in m:
    print i
f.close


aasasaf.jpg (98.62 KB, 下载次数: 301)

aasasaf.jpg


作者: shan91    时间: 2018-7-27 15:35
老师,条件都放这么宽松了,为什么一个数字都搜索不出来~~

正则式.png (2.6 KB, 下载次数: 290)

正则式.png


作者: crossin先生    时间: 2018-7-28 01:03
shan91 发表于 2018-7-27 15:35
老师,条件都放这么宽松了,为什么一个数字都搜索不出来~~

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

你直接用b这个变量就好了,何必多此一举,还弄错了
作者: 万里江山    时间: 2019-3-28 22:21
\bs.\S*e\b
作者: pigcare    时间: 2019-6-5 10:54
请教一个问题,问什么我用Pyhton3,识别不了\b、\d呢,IDE是Pycharm,代码如下:
import re
print(re.findall("s\S*?e","site sea sue sweet see case sse ssee loses"))
print(re.findall("s\S*e","site sea sue sweet see case sse ssee loses"))
print(re.findall("\bs*e\b"," site sea sue sweet see case sse ssee loses"))
print(re.findall("/d{5}","1234 146347 12345 64432 132526"))
运行结果:
D:\python\class_temp01\venv\Scripts\python.exe C:/Users/hp/.PyCharmCE2019.1/config/scratches/scratch.py
['site', 'se', 'sue', 'swe', 'se', 'se', 'sse', 'sse', 'se']
['site', 'se', 'sue', 'swee', 'see', 'se', 'sse', 'ssee', 'se']
[]
[]

Process finished with exit code 0
作者: crossin先生    时间: 2019-6-5 14:04
pigcare 发表于 2019-6-5 10:54
请教一个问题,问什么我用Pyhton3,识别不了\b、\d呢,IDE是Pycharm,代码如下:
import re
print(re.finda ...

规则前面要加 r,避免字符串转义
r"\bs*e\b"
作者: pigcare    时间: 2019-6-6 08:38
crossin先生 发表于 2019-6-5 14:04
规则前面要加 r,避免字符串转义
r"\bs*e\b"

这个转义感觉很难理解,加了r,不是查字符串里面的“\bs*e\b”,这样\b不就不能表示开头结尾了吗?转义后\b才表示开头结尾吧?
后来我把代码改了下:
import re
print(re.findall(r"\bs.e\b"," site  sea sue sweet see case sse ssee loses"))
运行结果:
D:\python\class_temp01\venv\Scripts\python.exe C:/Users/hp/.PyCharmCE2019.1/config/scratches/scratch.py
['sue', 'see', 'sse']

Process finished with exit code 0
为什么没有site呢?
作者: crossin先生    时间: 2019-6-6 13:39
pigcare 发表于 2019-6-6 08:38
这个转义感觉很难理解,加了r,不是查字符串里面的“\bs*e\b”,这样\b不就不能表示开头结尾了吗?转义后\ ...

你只有一个 . ,当然只匹配一个字符咯
你要么用 .*?




欢迎光临 Crossin的编程教室 (https://bbs.crossincode.com/) Powered by Discuz! X2.5