心得:又是充实的一天,望自己每天都过的充实起来~~~
为什么需要用到正则表达式,那我告诉你,不学正则表达式,你就体验不到那种快乐~它可以匹配任何你需要的字符。
1.函数方法:
match()
如果 string 的 开始位置 能够找到这个正则样式的任意个匹配,就返回一个相应的 匹配对象。如果没有返回None,只匹配开头。
>>> s="absdfab"
>>> m=re.match(r'sd',s)
>>> print(m)
None
search()
扫描整个 string 寻找第一个匹配的位置, 并返回一个相应的 匹配对象。如果没有匹配,就返回 None;可作为判断。
>>> s="absdfab"
>>> c=re.search(r'ab',s)
>>> c
<re.Match object; span=(0, 2), match='ab'>
>>> bool(c)
True
findall()
找到正则匹配的所有子字符串,并将它们作为列表返回。
>>> s="absdfab"
>>> f=re.findall(r'a',s)
>>> f
['a', 'a']
sub()
找到正则匹配的所有子字符串,并将它们替换成一个新的字符串再返回
>>> s="absdfab"
>>> u=re.sub('a','A',s)
>>> u
'AbsdfAb'
2.匹配
2.1普通字符匹配
绝大部分普通字符,比如 ‘A’, ‘a’, 或者 ‘0’,都是最简单的正则表达式。它们就匹配自身。你可以拼接普通字符,所以 last 匹配字符串 ‘last’
>>> s="sabcunlmrf;"
>>> a=re.findall(r'abc',s) #全部匹配
>>> b=re.findall(r'[abc]',s) #逐个匹配
>>> a
['abc']
>>> b
['a', 'b', 'c']
2.2特殊字符匹配
\d
匹配任何十进制数字;这等价于类 [0-9]。
>>> s='asd345kl2'
>>> b=re.findall(r'\d',s)
>>> b
['3', '4', '5', '2']
\D
匹配任何非数字字符;这等价于类 [^0-9]。
>>> s='asd345kl2'
>>> c=re.findall(r'\D',s)
>>> c
['a', 's', 'd', 'k', 'l']
\s
匹配任何空白字符;这等价于类 [ \t\n\r\f\v]。
>>> s='asd345 kl2'
>>> b=re.findall(r'\s',s)
>>> b
[' ']
\S
匹配任何非空白字符;这相当于类 [^ \t\n\r\f\v]。
>>> s='asd345 kl2'
>>> b=re.findall(r'\S',s)
>>> b
['a', 's', 'd', '3', '4', '5', 'k', 'l', '2']
\w
匹配任何字母与数字字符;这相当于类 [a-zA-Z0-9_]。
>>> s='asd345 kl2'
>>> b=re.findall(r'\w',s)
>>> b
['a', 's', 'd', '3', '4', '5', 'k', 'l', '2']
\W
匹配任何非字母与数字字符;这相当于类 [^a-zA-Z0-9_]。
>>> s='asd345 kl2'
>>> b=re.findall(r'\W',s)
>>> b
[' ']
.
(点) 在默认模式,匹配除了换行的任意字符。
>>> s='asd345 kl2'
>>> b=re.findall(r'.',s)
>>> b
['a', 's', 'd', '3', '4', '5', ' ', 'k', 'l', '2']
|
或者“or”运算符。 如果 A 和 B 是正则表达式,A|B 将匹配任何与 A 或 B 匹配的字符串。
>>> s='asd345 kl2'
>>> b=re.findall(r'a|k',s)
>>> b
['a', 'k']
^
在行的开头匹配。
>>> s='asd345 kl2'
>>> b=re.findall(r'^as',s)
>>> b
['as']
>>> b=re.findall(r'^s',s)
>>> b
[]
$
匹配行的末尾,定义为字符串的结尾,或者后跟换行符的任何位置。
>>> s='asd345 kl2'
>>> b=re.findall(r'l2$',s)
>>> b
['l2']
2.3 格式数量限定
*
对它前面的正则式匹配0到任意次重复, 尽量多的匹配字符串。 匹配次数大于等于零。
>>> s="helloooabc"
>>> b=re.findall(r'o*',s)
>>> b
['', '', '', '', 'ooo', '', '', '', '']
+
对它前面的正则式匹配1到任意次重复。 匹配次数大于一。
>>> s="helloooabc"
>>> b=re.findall(r'o+',s)
>>> b
['ooo']
?
对它前面的正则式匹配0到1次重复。 ab? 会匹配 ‘a’ 或者 ‘ab’。匹配次数一或零。
>>> s="helloooabc"
>>> b=re.findall(r'lo?',s)
>>> b
['l', 'lo']
“{m}”
对其之前的正则式指定匹配 m 个重复;少于 m 的话就会导致匹配失败。比如, a{6} 将匹配6个 ‘a’ , 但是不能是5个。
>>> s="helloooabc"
>>> b=re.findall(r'o{2}',s)
>>> b
['oo']
“{m, n}”
对正则式进行 m 到 n 次匹配,在 m 和 n 之间取尽量多。优先匹配多次
>>> s="helloooabc"
>>> b=re.findall(r'o{2,3}',s)
>>> b
['ooo']
{m,n}?
前一个修饰符的非贪婪模式,只匹配尽量少的字符次数。优先匹配少次
>>> s="helloooabc"
>>> b=re.findall(r'o{2,3}?',s)
>>> b
['oo']
3 贪婪模式和懒惰模式
重复修饰符 (*, +, ?, {m,n}, 等) 不能直接嵌套。正常使用过程中,我们的匹配模式属于贪婪模式,优先尽可能匹配多的,当我们在限定词之后加?之后,会变为懒惰模式,优先匹配少的。看例子:
>>> s="helloooabc"
>>> b=re.findall(r'o+',s) #一次匹配3个
>>> b
['ooo']
>>> b=re.findall(r'o+?',s) #一次匹配一个,匹配三次
>>> b
['o', 'o', 'o']
4.分组
(…)
(组合),匹配括号内的任意正则表达式,分几组,就会组成几个元素的元组。
>>> s='helloooabc'
>>> b=re.findall(r'(ab)(c)',s)
>>> b
[('ab', 'c')]
优先匹配括号内表达式,括号外匹配不捕获。
>>> s='asd345 kl2'
>>> b=re.findall(r'(d3)45',s)
>>> b
['d3']
(?:…)
正则括号的非捕获版本。 匹配在括号内的任何正则表达式,但该分组所匹配的子字符串 不能 在执行匹配后被获取或是之后在模式中被引用。
>>> s="asfgphone:95271314abcde"
>>> b=re.findall(r'phone:\d+',s)
>>> b
['phone:95271314'] #直接匹配会存在phone
>>> b=re.findall(r'(?:phone:)(\d+)',s) #使用分组?:会隐藏phone
>>> b
['95271314']
位置界定:
解释一下:你想匹配一段pass code,但这段code的格式和fail的格式一致,你只需要code,所以外加一个描述pass的形式,它会去匹配,但不返回。
(?=pattern) 后界定:
>>> s="1234567:pass 7654321:fail"
>>> b=re.findall('\d{7}:pass',s) #正常匹配pass code
>>> b
['1234567:pass']
>>> b=re.findall('\d{7}(?=:pass)',s) #位置界定pass code
>>> b
['1234567']
(?!pattern) 后不界定
去匹配不是pass 的code
>>> s="1234567:pass 7654321:fail"
>>> b=re.findall('\d{7}(?!:pass)',s)
>>> b
['7654321']
(?<=pattern) 前界定
匹配tian的电话号码
>>> s="tian:95271314 jian:12345678"
>>> b=re.findall('(?<=tian:)\d{8}',s)
>>> b
['95271314']
(?<!pattern) 前不界定
>>> s="tian:95271314 jian:12345678"
>>> b=re.findall('(?<!tian:)\d{8}',s)
>>> b
['12345678']
小练习:
1、长度为8-10的用户密码(以字母开头、数字、下划线)
^[a-zA-Z]\w{7,10}$
3、电子邮箱验证:
>>> s="www.309111985@qq.com www.123456789@163.com www.ashkjdbj@asdh"
>>> b=re.findall(r'w{3}\.\w+@\w+\.\w+',s)
>>> b
['www.309111985@qq.com', 'www.123456789@163.com']
4、URL地址验证:
#1种:
>>> s="https://www.baidu.com as"
>>> b=re.findall(r'https://w{3}\.\w+\.\w+',s)
>>> b
['https://www.baidu.com']
#第2种:
有些网站比较长~
>>> s="https://www.baidu.com as https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=python%E6%AD%A3%E5%88%99%E5%8C%B9%E9%85%8D%E7%BD%91%E7%AB%99&oq=%25E6%25AD%25A3%25E5%2588%2599%25E4%25B9%25A0%25E9%25A2%2598&rsv_pq=b217d62600343d21&rsv_t=e416DGFgpSiQ8nJHMn5vMSxeAkacXdM56vEB6s7qObv1C%2B%2FIIBvP4PyEDx4&rqlang=cn&rsv_enter=1&rsv_dl=tb&inputT=7127&rsv_sug3=54&rsv_sug1=8&rsv_sug7=101&rsv_sug2=0&rsv_sug4=8071&rsv_sug=9"
>>> b=re.findall(r'https://[^\s]*',s)
>>> b
['https://www.baidu.com', 'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=python%E6%AD%A3%E5%88%99%E5%8C%B9%E9%85%8D%E7%BD%91%E7%AB%99&oq=%25E6%25AD%25A3%25E5%2588%2599%25E4%25B9%25A0%25E9%25A2%2598&rsv_pq=b217d62600343d21&rsv_t=e416DGFgpSiQ8nJHMn5vMSxeAkacXdM56vEB6s7qObv1C%2B%2FIIBvP4PyEDx4&rqlang=cn&rsv_enter=1&rsv_dl=tb&inputT=7127&rsv_sug3=54&rsv_sug1=8&rsv_sug7=101&rsv_sug2=0&rsv_sug4=8071&rsv_sug=9']
>>>
5、电话号码的验证:我们知道在现实生活中,电话号码的区号可以是三位的也可以是4位的:
>>> s="012-12345678 0123-1234567 +8617521050772"
>>> b=re.findall(r'0\d{2}-\d{8}|0\d{3}-\d{7}|\+\d{13,15}',s)
>>> b
['012-12345678', '0123-1234567', '+8617521050772']
6、简单的身份证号验证:\d{15}|\d{18}$
>>> s='123456789123456 123456789123456789 12345678912345678X'
>>> b=re.findall(r'\d{14}\w{1}(?:\s)|\d{17}\w{1}',s)
>>> b
['123456789123456 ', '123456789123456789', '12345678912345678X']
附加:
当存在多个条件需要匹配时,如文本出现error或fail字符时,我们可以使用|来隔离匹配:
import re
r=re.search(r'error|fail',line)
search 用于判断
findall用于取值为到列表