Python-正则表达式

1,首先来一个基础的正则的例子
import re
text = "Hi, I am Shirley Hilton. I am his wife."
m = re.findall(r"hi",text)
if m:
    print m
else:
    print "not match"
输出:['hi', 'hi']
这是一个只招“hi”的表达式,正则是严格执行大小写的,不会匹配到“Hi”
而且这里是只匹配完全相同的字符


2,如果我们只想找到“hi”这个单词,而不把包含它的单词也算在内,那就
可以使用“\bhi\b”这个正则表达式。
“\b”在正则表达式中表示单词的开头或结尾,空格、标点、换行都算是单词的分割。
而“\b”自身又不会匹配任何字符,它代表的只是一个位置。所以单词前后的空格标
点之类不会出现在结果里。


在前面那个例子里,“\bhi\b”匹配不到任何结果。但“\bhi”的话就可以匹配到1个“hi”,
出自“his”。注意是“his”,而不是类似于“shi”这种,因为“his”之前是空格,“shi”前
是s,而“\b”是不匹配字符“s”的


3,前面例子中出现的  ['hi', 'hi']  ,[]表示满足括号中任意字符(注意是任意),比如“[hi]”,它就不是匹配“hi”了,而是匹配“h”或者“i”。如果把正则表达式改为“[Hh]i”,就可以既匹配“Hi”,又匹配“hi”了。
import re
text = "Hi, I am Shirley Hilton. I am his wife."
m = re.findall(r"[hi]",text)
if m:
    print m
else:
    print "not match"
输出:['i', 'h', 'i', 'i', 'h', 'i', 'i']


4,r"hi"
r是raw为加工的意思,表示不对字符串转义,
print “\bhi”    输出:hi
print r"\bhi"  输出:\bhi


如果你想在字符串里打“\”,则必须要打“\\”,print "\\bhi"  输出:\bhi


5,
re.findall(r"hi", text)
re是python里的正则表达式模块。findall是其中一个方法,用来按照提供的正则表达式,
去匹配文本中的所有符合条件的字符串。返回结果是一个包含所有匹配的list。


6,“.”和“*”,“\S”和“?”
“.”在正则表达式中表示除换行符以外的任意一个字符。
Hi, I am Shirley Hilton. I am his wife.


如果我们用“i.”去匹配,就会得到
['i,', 'ir', 'il', 'is', 'if']


与“.”类似的一个符号是“\S”,它表示的是不是空白符的任意字符。注意是大写字符S


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


import re
text = "Hi, I am Shirley Hilton. I am his wife."
m = re.findall(r"l.*e",text)
if m:
    print m
else:
    print "not match"
输出:['ley Hilton. I am his wife']


import re
text = "Hi, I am Shirley Hilton. I am his wife."
m = re.findall(r"l.*?e",text)
if m:
    print m
else:
    print "not match"
输出:['le', 'lton. I am his wife']


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

常用的元字符还有:
\w - 匹配字母或数字或下划线或汉字(我试验下了,发现3.x版本可以匹配汉字,但2.x版本不可以)
\s - 匹配任意的空白符
^ - 匹配字符串的开始
$ - 匹配字符串的结束
\S其实就是\s的反义,任意不是空白符的字符。同理,还有:
\W - 匹配任意不是字母,数字,下划线,汉字的字符
\D - 匹配任意非数字的字符
\B - 匹配不是单词开头或结束的位置
[a]的反义是[^a],表示除a以外的任意字符。[^abcd]就是除abcd以外的任意字符。
之前我们用过*、+、{}来表示字符的重复。其他重复的方式还有:
? - 重复零次或一次
{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+
这个条件加在表达式的最后。如果放在最前面,某些数据就可能会被优先匹配为这一条件。你可以写个测试用例体会一下两种结果的不同。


推荐一篇叫做《正则表达式30分钟入门教程》的文章https://deerchao.net/tutorials/regex/regex.htm

























































































猜你喜欢

转载自blog.csdn.net/weixin_40430845/article/details/79063249