python正则表达式入门(Crossin的编程教室例子)

# -- coding: utf-8 --
import re
text = "Hi , I am Shirley Hilton. I am his wife."

#[] 或的意思
m = re.findall(r"[Hh]i", text)#['Hi', 'hi', 'Hi', 'hi']
if m:
    print m
else:
    print 'not match'

#\b 是获取字符的开头或者结尾
m=re.findall(r"\bhi",text)#['hi']
print m

#r 起到转义的作用
m=re.findall("\bhi",text)#[]
print m


# .的作用是占位符 任意字符
m=re.findall(r"i.",text)#['i,', 'ir', 'il', 'is', 'if']
print m

#\S 不是空白符的任意字符

m=re.findall(r"i\S",text)#['ir', 'il', 'is', 'if']
print m

#会用“?”表示任意一个字符,“*”表示任意数量连续字符,这种被称为通配符。但在正则表达式中,
# 任意字符是用“.”表示,而“*”则不是表示字符,
# 而是表示数量:它表示前面的字符可以重复任意多次(包括0次),只要满足这样的条件,都会被表达式匹配上

#获取以I开头e结尾的字符
#贪婪匹配
m=re.findall(r"I.*e",text)#['I am Shirley Hilton. I am his wife']
print m

#懒惰匹配
m=re.findall(r"I.*?e",text)#['I am Shirle', 'I am his wife']
print m

'''
这是因为“*”在匹配时,会匹配尽可能长的结果。如果你想让他匹配到最短的就停止,
需要用“.*?”。如“I.*?e”,就会得到第二种结果。这种匹配方式被称为懒惰匹配,
而原本尽可能长的方式被称为贪婪匹配
'''



'''
最后留一道习题:
从下面一段文本中,匹配出所有s开头,e结尾的单词。

site sea sue sweet see case sse ssee loses
'''

question='site sea sue sweet see case sse ssee loses'

#启用\S的飞空字符
m=re.findall(r"\bs\S*?e\b",question)#['site', 'sue', 'see', 'sse', 'ssee']
print m
m=re.findall(r"\bs.*?e\b",question)#['site', 'sea sue', 'sweet see', 'sse', 'ssee']
print m


#abcgabc
#查询a开头c结尾的字符
t="abcgabc"
m=re.findall(r"a.*?c",t)
print m



#匹配电话
#[0-9]+
#\d
# +   加+后会匹配整体

t="3131 asdsa"
m=re.findall(r"[0-9]+",t)
print m
m=re.findall(r"\d",t)
print m

#匹配1开头的11位数据
#{}
t="1122311122211223231343242413213211132324243232"
t=re.findall(r"1\d{10}",t)
print t



'''
1.
我们已经了解了正则表达式中的一些特殊符号,如\b、\d、.、\S等等。这些具有特殊意义的专用字符被称作“元字符”。常用的元字符还有:

\w - 匹配字母或数字或下划线或汉字(我试验下了,发现3.x版本可以匹配汉字,但2.x版本不可以)
\s - 匹配任意的空白符
^ - 匹配字符串的开始
$ - 匹配字符串的结束

2.
\S其实就是\s的反义,任意不是空白符的字符。同理,还有:

\W - 匹配任意不是字母,数字,下划线,汉字的字符
\D - 匹配任意非数字的字符
\B - 匹配不是单词开头或结束的位置

[a]的反义是[^a],表示除a以外的任意字符。[^abcd]就是除abcd以外的任意字符。

3.
之前我们用过*、+、{}来表示字符的重复。其他重复的方式还有:

? - 重复零次或一次
{n,} - 重复n次或更多次
{n,m} - 重复n到m次

正则表达式不只是用来从一大段文字中抓取信息,很多时候也被用来判断输入的文本是否符合规范,或进行分类。来点例子看看:
^\w{4,12}$
这个表示一段4到12位的字符,包括字母或数字或下划线或汉字,可以用来作为用户注册时检测用户名的规则。(但汉字在python2.x里面可能会有问题)

\d{15,18}
表示15到18位的数字,可以用来检测身份证号码

^1\d*x?
以1开头的一串数字,数字结尾有字母x,也可以没有。有的话就带上x。

另外再说一下之前提到的转义字符\。如果我们确实要匹配.或者*字符本身,而不是要它们所代表的元字符,那就需要用\.或\*。\本身也需要用\\比如"\d+\.\d+"可以匹配出123.456这样的结果。

'''




'''
    来说上次的习题:
(021)88776543
010-55667890
02584453362
0571 66345673

一个可以匹配出所有结果的表达式是
\(?0\d{2,3}[) -]?\d{7,8}

解释一下:
\(?
()在正则表达式里也有着特殊的含义,所以要匹配字符"(",需要用"\("。?表示这个括号是可有可无的。

0\d{2,3}
区号,0xx或者0xxx

[) -]?
在区号之后跟着的可能是")"、" "、"-",也可能什么也没有。

\d{7,8}
7或8位的电话号码

可是,这个表达式虽然能匹配出所有正确的数据(一般情况下,这样已经足够),但理论上也会匹配到错误的数据。因为()应当是成对出现的,表达式中对于左右两个括号并没有做关联处理,例如(02188776543这样的数据也是符合条件的。

我们可以用正则表达式中的“|”符号解决这种问题。“|”相当于python中“or”的作用,它连接的两个表达式,只要满足其中之一,就会被算作匹配成功。

于是我们可以把()的情况单独分离出来:
\(0\d{2,3}\)\d{7,8}

其他情况:
0\d{2,3}[ -]?\d{7,8}

合并:
\(0\d{2,3}\)\d{7,8}|0\d{2,3}[ -]?\d{7,8}


使用“|”时,要特别提醒注意的是不同条件之间的顺序。匹配时,会按照从左往右的顺序,一旦匹配成功就停止验证后面的规则。假设要匹配的电话号码还有可能是任意长度的数字(如一些特殊的服务号码),你应该把
|\d+
这个条件加在表达式的最后。如果放在最前面,某些数据就可能会被优先匹配为这一条件。你可以写个测试用例体会一下两种结果的不同。
 '''
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值