match、search、findall、group(s) 区别
1 2 3 4 5 | import re # match findall经常用 # re.match() #从开头匹配,没有匹配到对象就返回NONE # re.search() #浏览全部字符,匹配第一个符合规则的字符串 # re.findall() # 将匹配到的所有内容都放置在一个列表中 |
一、match有两种情况
------- 有分组 ------取匹配到的正则再次取其部分内容
1 2 3 4 5 6 | origin = "hello alex sadf dsaf" r = re.match( "(h)\w+" ,origin) print (r.group()) # hello 获取匹配所有结果 print (r.groups()) #('h',) #获取模型中匹配到的分组 没有分组则为空元组 r = re.match( "(?P<n1>h)(?P<n2>\w+)" ,origin) #获取模型中匹配到的分组中所有执行力key的组 ?P<KEY>VALUE {'n2': 'ello', 'n1': 'h'} print (r.groupdict()) #?P<KEY>VALUE {'n2': 'ello', 'n1': 'h'} |
------- 无分组 ------
1 2 3 4 | r = re.match( "h\w+" ,origin) print (r.group()) # 获取匹配所有结果 hello print (r.groups()) #获取模型中匹配到的分组 () print (r.groupdict()) #获取模型中匹配到的分组 {} |
二、groups、group、groupdict
1 2 3 4 | print (r.group()) # hello 获取匹配所有结果 print (r.groups()) #('h',) #获取模型中匹配到的分组 没有分组则为空元组 r = re.match( "(?P<n1>h)(?P<n2>\w+)" ,origin) #获取模型中匹配到的分组中所有执行力key的组 ?P<KEY>VALUE {'n2': 'ello', 'n1': 'h'} print (r.groupdict()) #?P<KEY>VALUE {'n2': 'ello', 'n1': 'h'} |
三、search两种情况
search 不用从开头匹配,而是匹配全局整个字符串,一旦又符合就退出
------- 有分组 ------
1 2 3 4 5 6 | origin = "hello alex alix bcd dsfa lefg abc 199" r = re.search( "a(\w+)" ,origin) print (r.group()) #alex print (r.groups()) #('lex',) r = re.search( "(?P<key1>a)(?P<key2>(\w+))" ,origin) print (r.groupdict()) #{'key1': 'a', 'key2': 'lex'} |
------- 无分组 ------
1 2 3 4 5 | origin = "hello alex alix bcd dsfa lefg abc 199" r = re.search( "ali\w+" ,origin) print (r.group()) #alix print (r.groups()) #() print (r.groupdict()) #{} |
四、findall
# 1 匹配到之后,就抽离,继续从下一个字符开始匹配
1 2 3 | origin = "a2b3c4d5" a = re.findall( "\d+\w\d+" ,origin) #['2b3', '4d5'] print (a) |
# 2 空值也会挨个字符去匹配,结尾后,还要继续多匹配一次
1 2 | num = "asd" print (re.findall("",num)) # ['', '', '', ''] |
# 无分组
1 2 3 4 5 | origin = "hello alex alix bcd dsfa lefg abc 199" print (re.findall( "a\w+" ,origin)) # ['alex', 'alix', 'abc'] print (re.findall( "(a\w+)" ,origin)) #['alex', 'alix', 'abc'] print (re.findall( "a(\w+)" ,origin)) #组 groups ['lex', 'lix', 'bc'] print (re.findall( "(a)(\w+)(x)" ,origin)) # [('a', 'le', 'x'), ('a', 'li', 'x')] 将 三个分组匹配到的做成元组 放到列表作为一个元素 |
findall 的特点
1 2 3 4 5 6 7 8 9 10 11 | 分组匹配 * 贪婪匹配: 比如如下的asd 为一个分组,而一旦遇到asd开始的字符串,如果 后面还是asd也会匹配,这就是贪婪匹配。 findall 特性: 1 有几个分组返回几个内容:,并将返回内容放到元组内 作为列表的一个元素。 2 即尽管 * 匹配到了两个asd ,但是因为是贪婪虚拟匹配出的,有一个分组,所以, 只会,取一个。 3 而findall默认只取最后一组匹配的内容,故此 只返回最后一组asd 4 findall 如果正则能有空的匹配的话,那么匹配字符串最后还会匹配到一个空 5 多个分组匹配到做成元组,当成列表的一个元素 6 多个分组,查找顺序,外到内,左到右 ((\w)(\w)){ 2 ,} 先是找到 2 个字母的,再在这两个字母里面进行局部分组 |
# 1 特性 1 2 3 4
1 | print (re.findall(r '(asd)*' , 'asdasd' )) #['asd', ''] |
# 2 如下,默认+可以第一次 就匹配到 1asd2asd 但由于前面只有1个分组,只能返回后面的4位了
1 2 | n = re.findall( "(\dasd)+" , "1asd2asdp2asds" ) # ['2asd', '2asd'] print (n) |
# 3 如下,默认*可以第一次 就匹配到 1asd2asd 但由于前面只有1个分组,只能返回后面的4位了
#但是*还可以表示0次,故再遇到p的时候,空就能匹配了,而且,最后还有个s也匹配到空,结尾还默认还会匹配到空
1 2 | n = re.findall( "(\dasd)*" , "1asd2asdp2asds" ) # ['2asd', '', '2asd', '', ''] print (n) |
#4 匹配,最多四个字母,因此alex都找到了,但是只有一个分组,所以只返回最后一个\w故x
1 2 3 | a = "alex" n = re.findall( "(\w){4}" ,a) print (n) # ['x'] |
#5 这里findall 匹配分组是一个字母匹配到了,而*是贪婪匹配,四个字母都匹配就取到了四个字母,而正则分组只有一个,因此只取最后一个
1 2 3 | a = "alex" n = re.findall( "(\w)*" ,a) print (n) # ['x', ''] |
#6 由于从外到内, 所以匹配两个字母的 al 匹配到了,ex也匹配到了,外部分组1个,因此ex,而内部从左到右又会匹配。
1 2 3 | a = "alex" n = re.findall( "((\w)(\w)){2,}" ,a) print (n) # [('ex', 'e', 'x')] |
#7 会匹配ax alex alex acd 但是贪婪匹配的分组只有 1个 因此 ax ax ax ad
1 2 3 | origin = "hello ax lex bed alex lge alex acd 19" n = re.findall( "(a)(\w)*" , origin) print (n) #[('a', 'x'), ('a', 'x'), ('a', 'x'), ('a', 'd')] |