文章目录
正则表达式与re模块
一 什么是正则表达式
由一系列特殊字符拼接而成的表达式/规则,它描述了一种字符串匹配的模式。
在python中,它内嵌在Python解释器中,并通过re模块实现。正则表达式被编译成一系列的字节码,然后由用C编写的匹配引擎执行。
二 为什么有正则表达式
正则表达式用于从一个大字符串中匹配出符合规则的子字符串。
三 正则表达式如何使用
1 正则表达式的基本用法
1.1 元字符
万物有源,正则也是如此,元字符是构成正则表达式的一种基本元素。
# 基本的元字符:
元字符 | 说明 |
---|---|
. | 匹配除换行符以外的任意字符 |
\w | 匹配字母或数字或下划线或汉字 |
\s | 匹配任意的空白符 |
\d | 匹配任意数字 |
\b | 匹配单词的开始或结束 |
^ | 匹配字符串的开始 |
$ | 匹配字符串的结束 |
有了元字符之后,我们就可以利用这些元字符来写一些简单的正则表达式,比如:
1.2.重复限定符
为了处理重复的书写元字符的问题,正则表达式提供了一些重复限定符,把重复部分用何使的限定符替代:
语法 | 说明 |
---|---|
* | 左侧字符重复零次或更多次 |
+ | 左侧字符重复一次或更多次 |
? | 左侧字符重复零次或一次 |
{n} | 左侧字符重复n次 |
{n, } | 左侧字符重复n次或更多次 |
{n, m} | 左侧字符重复n到m次 |
1.3.分组——"()"
限定符是作用在与他左面最近的一个字符身上,若想要两个或两个以上字符同时被限定,则需要使用到小括号()来做分组,也就是括号中的内容作为一个整体。
语法 | 说明 |
---|---|
(ab) | 根据分组条件限定,但仅显示分组内的内容ab |
(?:ab) | 根据分组条件限定,但是不仅仅显示分组内的内容,?: 取消了仅显示分组内容的限制 |
1.4.转义——" \ "
我们知道了()在表达式内有分组这一特殊的含义,那么我们如何进行匹配字符串本身就包括特殊意义的符号呢?针对这种情况,正则提供了转义的方式,也就是要把这些元字符、限定符或者关键字转义成普通的字符,就是在这些字符前面加一个" \ ",可以实现转义效果。
由于python中" \ "也有转义的效果,那么:
# 字符串"a\c"如何使用正则模块进行匹配?有两种方式:
1) "a\\\\c"
2) r"a\\c"
"""
解析:
python语法进行了一次转义,而Cpython解释器自带的正则模块又进行了一次转义,两次转义,解决python语法中的转义可以使用"\"或者原生字符串r解决,正则中的只能使用"\"解决。
"""
1.5.条件或——"|"
正则中针对并列的条件,提供了"|"代表“或”,也叫分支条件,当满足正则中分支条件的任一条件时,都会当成是匹配成功。
1.6.区间——"[]"
正则中提供了一个元字符中括号来表示区间条件,也可以理解为区间内的字符,属于或关系。
元字符 | 说明 |
---|---|
[0-9] | 代表限定条件是0-9中的任意数字。 |
[a-zA-Z] | 代表限定条件是英文字母,[a-z]可单独代表小写字母。 |
[-+] | 限定字符是"-“或”+",当"-"不代表区间范围含义时,必须放在开始或末尾。 |
2 在python中使用re模块
2.1 python中常用的元字符及其含义
模式 | 含义 |
---|---|
\w | 匹配字母、数字、下划线及汉字 |
\W | 匹配非字母、数字、下划线及汉字 |
\s | 匹配任意空白字符,等价于[\t\n\r\f] |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于[0-9] |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串 |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置 |
\n | 匹配一个换行符 |
\t | 匹配一个制表符 |
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾 |
. | 匹配任意字符,除了换行符,当re.DOTALL 标记被指定时,则可以匹配包括换行符的任意字符 |
[…] | 用来表示匹配一组字符串,单独列出:[amk]匹配"a",“m"或"k”,特殊字符在中括号内没有特殊含义 |
[^…] | 不在[]中的字符:若…代表abc,则匹配除a,b,c外的任意字符 |
* | 匹配0个或多个,贪婪方式 |
+ | 匹配1个或多个,贪婪方式 |
? | 匹配0个或一个由前面的正则表达式定义的片段, 非贪婪方式限定 |
{n} | 精确匹配n个前面表达式 |
{n, m} | 匹配n到m次由前面的正则表达式定义的片段,贪婪方式 |
a|b | 匹配a或b |
() | 匹配括号内的表达式,也表示一个组 |
2.2 普通匹配示例
# 一对一的匹配
'hello'.replace(old,new)
'hello'.find('partten')
2.3 正则匹配示例
2.3.1 \w
print(re.findall('\w\w\w', "h ello 123_ (0")) # ['ell', '123']
2.3.2 \W
print(re.findall('\W',"h ello 123_ (0")) # [' ', ' ', ' ', '(']
2.3.3 \s
print(re.findall('\s', "h e\tll\no 123_ (0")) # [' ', '\t', '\n', ' ', ' ']
print(re.findall('\w\s',"h ello 123_ (0")) # ['h ', 'o ', '_ ']
2.3.4 \S
print(re.findall('\S', "h e\tll\no 123_ (0")) # ['h', 'e', 'l', 'l', 'o', '1', '2', '3', '_', '(', '0']
2.3.5 \d
print(re.findall('\d', "h e\tll\no 123_ (0")) # ['1', '2', '3', '0']
2.3.6 \D
print(re.findall('\D', "h e\tll\no 123_ (0")) # ['h', ' ', 'e', '\t', 'l', 'l', '\n', 'o', ' ', '_', ' ', '(']
print(re.findall("a\db", "a1b a2b a b aab aaaaaaaa1b a2c a22c a 3c")) # ['a1b', 'a2b', 'a1b']
2.3.7 \n与\t
msg = """h e\tll\n\no 123_ (0
\t1
2
3
"""
print(re.findall('\n', msg)) # ['\n', '\n', '\n', '\n', '\n', '\n']
print(re.findall('\t', msg)) # ['\t', '\t']
print(re.findall(' ', msg)) # [' ', ' ', ' ', ' ', ' ', ' ', ' ']
2.3.8 ^与$
print(re.findall("^egon", "egon asdf 213123 egonafsadfegon")) # ['egon']
print(re.findall("egon$", "egon asdf 213123 egonafsadfegon")) # ['egon']
print(re.findall("egon$", "egon asdf 213123 egonafsadfegon ")) # []
print(re.findall("a\w\w\wc", "ab12c3c a213c")) # ['ab12c', 'a213c']
print(re.findall("^a\w\w\wc$", "ab12c3c a213c")) # []
print(re.findall("^a\w\w\wc$", "ab_2c")) # ['ab_2c']
2.3.9 . 与[]、中括号内取反、*、+、{n,m}、?、. *、
2.3.9.1 "."
代表匹配一个字符,该字符可以是任意除换行符外的字符
print(re.findall("a\db", "a1b a2b aab aaaaaaab a+b a-b a c")) # ['a1b', 'a2b']
print(re.findall("a\wb", "a1b a2b aab aaaaaaab a+b a-b a c")) # ['a1b', 'a2b', 'aab', 'aab']
print(re.findall("a.b", "a1b a2b aab aaaaaaab a+b a-b a b a c")) # ['a1b', 'a2b', 'aab', 'aab', 'a+b', 'a-b', 'a b']
print(re.findall("a.b", "a1b a2b aab aaaaaaab a\tb a-b a\nb a c", re.DOTALL)) # ['a1b', 'a2b', 'aab', 'aab', 'a\tb', 'a-b', 'a\nb']
2.3.9.2 []
:代表匹配一个字符,我们可以指定该字符的范围,特殊字符在[]内就没有特殊含义了
print(re.findall("a[+-]b", "a1b a2b aab aaaaaaab a+b a-b a c")) # ['a+b', 'a-b']
print(re.findall("a[.*/+-]b", "a.b a2b a*b a/b aab aaaaaaab a+b a-b a c")) # ['a.b', 'a*b', 'a/b', 'a+b', 'a-b']
print(re.findall("a[a-z]b", "a.b a2b a*b a/b aab aaaaaaab a+b a-b a c")) # -放在[]内的开头或结果
# ['aab', 'aab']
print(re.findall("a[a-zA-Z]b", "a.b a2b a*b a/b aAb aCb aab aaaaaaab a+b a-b a c")) # -放在[]内的开头或结果
# ['aAb', 'aCb', 'aab', 'aab']
print(re.findall("a\db", "a.b a2b a*b a/b aAb aCb aab aaaaaaab a+b a-b a c")) # ['a2b']
print(re.findall("a[0-9]b", "a.b a2b a*b a/b aAb aCb aab aaaaaaab a+b a-b a c")) # ['a2b']
2.3.9.3 [^]
对上尖号后的内容取反
print(re.findall("a[^0-9]b", "a.b a2b a*b a/b aAb aCb aab aaaaaaab a+b a-b a c")) # ['a.b', 'a*b', 'a/b', 'aAb', 'aCb', 'aab', 'aab', 'a+b', 'a-b']
2.3.9.4 *
: 左边那个字符出现0次或者无穷次
print(re.findall("ab*", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['a', 'ab', 'abb', 'abbbbbbbbbbbb']
2.3.9.5 +
: 左边那个字符出现1次或者无穷次
print(re.findall("ab+", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['ab', 'abb', 'abbbbbbbbbbbb']
2.3.9.6 {n,m}
: 左边那个字符出现n次到m次
print(re.findall("ab{0,}", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['a', 'ab', 'abb', 'abbbbbbbbbbbb']
print(re.findall("ab*", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['a', 'ab', 'abb', 'abbbbbbbbbbbb']
print(re.findall("ab{1,}", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['ab', 'abb', 'abbbbbbbbbbbb']
print(re.findall("ab+", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['ab', 'abb', 'abbbbbbbbbbbb']
print(re.findall("ab{2,5}", "a ab abb abbb abbbb abbbbbbbb abbbbbbbbbbbb bbbbbbbbb")) # ['abb', 'abbb', 'abbbb', 'abbbbb', 'abbbbb']
2.3.9.7 ?
: 左边那个字符出现0次到1次,进行非贪婪限定
print(re.findall("ab?", "a ab abb abbbbbbbbbbbb bbbbbbbbb")) # ['a', 'ab', 'ab', 'ab']
2.3.9.8 .*
: 匹配所有(除换行符)
print(re.findall("a.*b", "123 a1231-==-000b123123123123123b")) # ['a1231-
print(re.findall("a.*?b", "123 a1231-==-000b123123123123123b")) # ['a1231-==-000b']
# 例1:re模块可以将一个正则匹配保存起来
msg = '<a href="https://pan.baidu.com/s/1skWyTT7" target="_blank"><strong><span style="color: #ff0000;">原理图:https://pan.baidu.com/s/1skWyTT7</span></strong></a><a href="https://www.baidu/com">"点我啊"</a>'
url_pattern = re.compile('href="(.*?)"')
res = url_pattern.findall(msg)
print(res) # ['https://pan.baidu.com/s/1skWyTT7', 'https://www.baidu/com']
res = url_pattern.findall('<a href="www.sina.com.cn"></a>') # ['www.sina.com.cn']
# 例2:当re.DOTALL标记被指定时,.可以匹配包括换行符的任意字符
print(re.findall("a.*b", "a1b a+b a-b a\nb a\tb", re.DOTALL)) # ['a1b a+b a-b a\nb a\tb']
2.3.10 ():分组及取消分组
print(re.findall('ab+', 'ababab123')) # ['ab', 'ab', 'ab']
print(re.findall('(ab)+123', 'ababab123')) # ['ab'],匹配到末尾的ab123中的ab
print(re.findall('(?:ab)+123', 'ababab123')) # findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容
# ['ababab123']
2.3.11 |:或者
print(re.findall("compan(?:ies|y)", "Too many companies have gone bankrupt, and the next one is my company'")) # ['companies', 'company']
print(re.findall("\d+\.?\d*", "as9fdasl333...4444df1111asdf3333dfadf333.44dafadf3.5555asdfsafd.5555")) # ['9', '333.', '4444', '1111', '3333', '333.44', '3.5555', '5555']
2.3.12 \ 转义符
print(re.findall('a\\\\c','a\c a1c aac')) # ['a\\c']
print(re.findall(r'a\\c', 'a\c a1c aac')) # ['a\\c']
# 对于正则来说a\\c确实可以匹配到a\c,但是在python解释器读取a\\c时,会发生转义,然后交给re去执行,所以抛出异常
2.4 re模块提供的方法介绍
2.4.1 re.findall(pattern, string, flags=0)
# 找到所有,从头找到尾,全部找出。
# .* ==> 任意字符 .*?==> 非贪婪限定后的
msg = '<a href="https://pan.baidu.com/s/1skWyTT7" target="_blank"><strong><span style="color: #ff0000;">原理图:https://pan.baidu.com/s/1skWyTT7</span></strong></a><a href="https://www.baidu/com">"点我啊"</a>'
print(re.findall('href=".*?"', msg)) # ['href="https://pan.baidu.com/s/1skWyTT7"', 'href="https://www.baidu/com"']
print(re.findall('href=".*"', msg)) # ['href="https://pan.baidu.com/s/1skWyTT7" target="_blank"><strong><span style="color: #ff0000;">原理图:https://pan.baidu.com/s/1skWyTT7</span></strong></a><a href="https://www.baidu/com">"点我啊"']
print(re.findall('e', 'alex make love')) # ['e', 'e', 'e'],返回所有满足匹配条件的结果,放在列表里
print(re.search('e', 'alex make love')) # <re.Match object; span=(2, 3), match='e'> e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。
2.4.2 re.search(pattern, string, flags=0)
# 从头找到尾,找到第一个停下返回输出结果。加上.group()可以输出实际的结果。
print(re.search("\d+\.?\d*", "1.3 aa3.44aaa").group()) # 1.3
print(re.search("\d+\.?\d*", "asdfsadf")) # None
2.4.3 re.match(pattern, string, flags=0)
# 从第一个字符开始匹配,相当于^research。
print(re.search("\d+\.?\d*", " 1.3 aa3.44aaa")) # <re.Match object; span=(1, 4), match='1.3'>
print(re.match("\d+\.?\d*", "1.3 aa3.44aaa")) # <re.Match object; span=(0, 3), match='1.3'>
print(re.match("\d+\.?\d*", " 1.3 aa3.44aaa")) # None
2.4.4 re.split(self, *args, **kwargs)
# 字符串的切分。
msg = "egon:18-male=10"
print(msg.split(':')) # ['egon', '18-male=10']
print(re.split('[:=-]', msg)) # ['egon', '18', 'male', '10']
2.4.5 re.compile(pattern, flags=0)
# re.compile()是用来优化正则的,它将正则表达式转化为对象,re.search(pattern, string)的调用方式就转换为 pattern.search(string)的调用方式,多次调用一个正则表达式就重复利用这个正则对象,可以实现更有效率的匹配
# re.compile()生成的是正则对象,单独使用没有任何意义,需要和findall(), search(), match()搭配使用
msg = '<a href="https://pan.baidu.com/s/1skWyTT7" target="_blank"><strong><span style="color: #ff0000;">原理图:https://pan.baidu.com/s/1skWyTT7</span></strong></a><a href="https://www.baidu/com">"点我啊"</a>'
url_pattern = re.compile('href="(.*?)"')
res = url_pattern.findall(msg)
print(res) # ['https://pan.baidu.com/s/1skWyTT7', 'https://www.baidu/com']
res = url_pattern.findall('<a href="www.sina.com.cn"></a>') # ['www.sina.com.cn']
3 正则表达式的高级用法
3.1 零宽断言
3.1.1 断言
-正则中的断言,指的是正则可以指明在指定的内容的前面或后面会出现满足指定规则的内容。意思是正则也可以像人类那样断定什么什么,比如"abc123def", 正则可以用断言找出123前面有abc,也可以找出123后面有def。
3.1.2 零宽
-就是没有宽度,在正则中,断言只匹配位置,不占字符,也就是说,匹配的结果不会返回断言本身。
3.1.3 断言类型之:正向先行断言(正前瞻)
语法:(?=pattern)
作用:匹配pattern表达式之前的前面内容,不返回本身。
3.1.4 断言类型之:正向后行断言(正后顾)
语法:(?<=pattern)
作用:匹配pattern表达式的后面的内容,不返回本身。
3.1.5 断言类型之:负向先行断言(负前瞻)
语法:(?!pattern)
作用:匹配非pattern表达式前面的内容,不返回本身。
3.1.6 断言类型之:负向后行断言(负后顾)
语法:(?<!pattern)
作用:匹配非pattern表达式后面的内容,不返回本身。
3.2 捕获和非捕获
单纯说到捕获,他的意思是匹配表达式,但捕获通常和分组联系在一起,也就是”捕获组“。
捕获组:匹配子表达式的内容,把匹配结果保存到内存中以数字编号或显示命名的组里,以深度优先进行编号,之后可以通过序号或名称来使用这些匹配结果。
3.2.1 数字编号捕获组
语法:(exp)
解释:从表达式左侧开始,每出现一个左括号和它对应的右括号之间的内容为一个分组,在分组中,第0组为整个表达式,第一组开始为分组。
以固定电话为例:020-85653333
他的正则表达式为:(0\d{2})-(\d{8})
按照左括号的顺序,这个表达式有如下分组:
序号 | 编号 | 分组 | 内容 |
---|---|---|---|
0 | 0 | (0\d{2})-(\d{8}) | 020-85653333 |
1 | 1 | (0\d{2}) | 020 |
2 | 2 | (\d{8}) | 85653333 |
3.2.2 命名编号捕获组
语法:(?< name>exp)
解释:分组的命名由表达式中的name指定。
比如区号也可以这样写:(?< quhao>\0\d{2})-(?< haoma>\d{8})
按照左括号的顺序,这个表达式有如下分组:
序号 | 编号 | 分组 | 内容 |
---|---|---|---|
0 | 0 | (0\d{2})-(\d{8}) | 020-85653333 |
1 | quhao | (0\d{2}) | 020 |
2 | haoma | (\d{8}) | 85653333 |
3.2.3 非捕获组
语法:(?:exp)
解释:和捕获组刚好相反,它用来标识那些不需要捕获的分组,说的通俗一点,就是可以根据需要去保存你的分组。
比如上面的正则表达式,程序不需要用到第一个分组,那就可以这样写:
(?:\0\d{2})-(\d{8})
序号 | 编号 | 分组 | 内容 |
---|---|---|---|
0 | 0 | (0\d{2})-(\d{8}) | 020-85653333 |
1 | 1 | (0\d{8}) | 85653333 |
3.3.反向引用
捕获会返回一个捕获组,这个分组时保存在内存中,不仅可以在正则表达式外部通过程序进行引用,也可以在正则表达式内部进行引用,这种引用方式就是反向引用。
根据捕获组的命名规则,反向引用可分为:
1) 数字编号组反向引用:\k或\number
2) 命名编号组反向引用:\k或者\'name'
# 作用:
-它的作用主要是用来查找一些重复的内容或者做替换指定字符。与分组配合使用。
3.4 贪婪和非贪婪
3.4.1 贪婪
"贪婪匹配":当正则表达式中包含能接受重复的限定符时,通常的行为是(在使整个表达式能得到匹配的前提下) 匹配尽可能多的字符,这匹配方式叫做贪婪匹配。
"特性":一次性读入整个字符串进行匹配,每当不匹配就舍弃最右边一个字符,继续匹配,依次匹配和舍弃(这种匹配-舍弃的方式也叫做回溯) ,直到匹配成功或者把整个字符串舍弃完为止,因此它是一种最大化的数据返回,能多不会少。
多个贪婪在一起时,如果字符串能满足他们各自最大程度的匹配时,就互不干扰,但如果不能满足时,会根据深度优先原则,也就是从左到右的每一个贪婪量词,优先最大数量的满足,剩余再分配下一个量词匹配。
3.4.2 懒惰(非贪婪)
"懒惰匹配":当正则表达式中包含能接受重复限定符时,通常的行为是(在使整个表达式能得到匹配的前提下) 匹配尽可能少的字符,这匹配方式叫做懒惰匹配。
"特性":从左到右,从字符串的最左边开始匹配,每次试图不读入匹配字符,匹配成功,则完成匹配,否则读入一个字符再匹配,依次循环(读入字符、匹配) 直到匹配成功或者把字符串的字符匹配完为止。
懒惰量词是在贪婪量词后面加个"?"
代码 | 说明 |
---|---|
*? | 重复任意次,但尽可能少重复 |
+? | 重复1次或更多次,但尽可能少重复 |
?? | 重复0次或一次,但尽可能少重复 |
{n, m}? | 重复n到m次,但尽可能少重复 |
{n, }? | 重复n次以上,但尽可能少重复 |
4 python中应用案例:
import re
# 1、匹配密码,密码必须是由6位数字与字母组成,并且不能是纯数字也不能是纯字母
# 1.1 知识点:# ?!pattern,表示在没有配到pattern的字符串的前提下,再进行后续的正则表达式匹配,后续匹配仍然从被匹配字符串的头开始
# 1.2 答案:
print(re.search("(?!^[0-9]+$)(?!^[a-zA-Z]+$)^[0-9A-Za-z]{6}$", "123asf").group()) # 123asf
# 1.3 解释:
# 上述正则的意思为:在匹配(?!^[0-9]+$)以及(?!^[a-zA-Z]+$)过后,如果字符串成功后再从头去匹配(?!^[a-zA-Z]+$),最终匹配完。
while True:
pwd = input("please your password: ").strip() # 比如输入:123asF
pwd_partten = re.compile("(?=.*[a-zA-Z])(?=.*[0-9])^([a-zA-Z0-9]){6}$")
if pwd_partten.search(pwd) is None:
print('密码强度不够')
else:
break
# 2、匹配密码,密码强度:强,必须包含大写,小写和数字,和特殊字符(!,@,#,%,&),且大于6位
# 2.1 知识点:# ?=pattern,表示在配到pattern的字符串的前提下,再进行后续的正则表达式匹配,后续匹配仍然从被匹配字符串的头开始
# 2.2 答案:
while True:
pwd = input("please your password: ").strip() # 比如输入:Aa3@adf123
pwd_pattern = re.compile("(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#%&])^([a-zA-Z0-9!@#%&]){6,}$")
if pwd_pattern.search(pwd) is None:
print("密码强度不够")
else:
break
# 2.3 解释:
# 上述正则表达式的意思:
# (1) 首先是(?=.*[A-Z])匹配,.*表示密码中可以包含多个字符,[A-Z]代表密码中需要包含至少一个大写字母,注意一定不要去掉.*写成(?=[A-Z]),那样表示密码只能由一个字符组成,该字符是大写字母
# (2) 其次是(?=.*[a-z])匹配,同上,确保密码中必须至少有一个小写字母
# (3) 然后是(?=.*[0-9])匹配,同上,确保密码中必须至少有一个数字
# (4) 然后是(?=.*[!@#%&])匹配,同上,,确保密码中必须至少有一个特殊符号!@#%&
# (5) 最后是^([a-zA-Z0-9!@#%&]){6,}$,确保密码是由[a-zA-Z0-9!@#%&]字符构成,至少有6位
# 3、匹配email
print(re.findall("(?:[a-zA-Z0-9]+)@(?:[0-9a-zA-Z]+).com","18611323113@163.com xxx@qq.com"))
# 4、匹配身份证
your_id=input(">>: ").strip()
print(re.findall("^([0-9]){17}([0-9]|X)$",your_id)) # 17个数字组成,最后一个字符可以是数字或X
print(re.findall("^(?:[0-9]){17}(?:[0-9]|X)$", "32032119920822222X")) # ['32032119920822222X']
# 5、匹配用户名,包含字母或者数字,且8位
print(re.findall("^[0-9a-zA-Z]{8}$","egonlinh"))
# 5.1、要求输入的内容只能是汉字
# name=input('>>: ').strip()
# print(re.search(r'[\u4E00-\u9fa5]+',name))
print(re.search(r"[\u4E00-\u9fa5]+", '矮根')) # <re.Match object; span=(0, 2), match='矮根'>
# 6、取出字符串里的数字
# print(re.findall(r'\d+(?:\.\d+)?', 'sww123kw11.333e2lkd'))
print(re.findall(r"\d+(?:\.\d+)?", 'sww123kw11.333e2lkd')) # ['123', '11.333', '2']
#————————————————————————————# ?——>0或1个小数点及后续数字,为整数准备
print(re.findall(r"\d+(?:\.\d+)", 'sww123kw11.333e2lkd')) # ['11.333']
# 7、取出所有负整数
# print(re.findall(r'-\d+', '-12,3,54,-13.11,64,-9')) # 错误答案
# print(re.findall(r'(?!-\d+\.\d+)-\d+', '-12,3,54,-13.11,64,-9')) # 正确答案
print(re.findall(r'-\d+', '-12,3,54,-13.11,64,-9')) # 未排除浮点数
print(re.findall(r'(?!-\d+\.\d+)-\d+', '-12,3,54,-13.11,64,-9'))
#——————————————————# 先排除负数的浮点数
# 8、所有数字
# print(re.findall(r'\-?\d+(?:\.\d+)?', '-12.9,3.92,54.11,64,89,-9,-45.2'))
print(re.findall(r"\-?\d+(?:\.\d+)?", '-12.9,3.92,54.11,64,89,-9,-45.2')) # ['-12.9', '3.92', '54.11', '64', '89', '-9', '-45.2']
# 9、所有负数
# print(re.findall(r'\-\d+(?:\.\d+)?', '-12.9,3.92,54.11,64,89,-9,-45.2'))
print(re.findall(r"\-\d+(?:\.\d+)?", '-12.9,3.92,54.11,64,89,-9,-45.2')) # ['-12.9', '-9', '-45.2']
# 10、所有的非负浮点数
# print(re.findall(r'\d+\.\d+', '-12.9,3.92,54.11,64,89,-9,-45.2'))
print(re.findall(r"\d+(?:\.\d+)?", '-12.9,3.92,54.11,64,89,-9,-45.2')) # ['12.9', '3.92', '54.11', '64', '89', '9', '45.2']
# 11、
msg = """
中文名 贝拉克·侯赛因·奥_巴马
外文名 Barack Hussein O_bama II
别名 欧_巴马
性 别 男
国籍 美国
民 族 德裔族
出生地 美国夏威夷州檀香山
出生日期 1961年8月4日
职 业政治家、律师、总统
毕业院校 哥伦比亚大学,哈佛大学
信 仰新教
主要成就 1996年伊利诺伊州参议员
主要成就 美国第56届、57届总统 2009年诺贝尔和平奖获得者 时代周刊年度风云人物2008、2011 任期内清除本·拉登
代表作品 《我相信变革》《我父亲的梦想》《无畏的希望》
所属政党美国民主党
血 型 AB型
学 院西方学院
妻 子 米歇尔·拉沃恩·奥_巴马
"""
# # 外文名
print(re.findall("外文名 (.*)", msg))
#
# # 出生日期
print(re.findall('出生日期 (\d{4})年(\d+)月(\d+)日', msg))
#
# # 妻子姓名
print(re.findall('妻 子 (\S+)', msg))
print(re.findall('妻 子 (.*)', msg))
参考资料:
https://juejin.im/post/6844903680349585422