一、数量词
数量词,即{n,m}形式的正则,m和n均为非负整数,其中n<=m,用于规定最少匹配n次且最多匹配m次,注意在逗号和两个数之间不能有空格。例如,”o{1,3}”将匹配”fooooood”中的前三个o为一组,后三个o为一组,而”o{0,1}”等价于”o?”;
下面是一个示例:使用正则方式找出字符串中的3个单词
string = “python 111java678php”
分析:连续的至少2个字符的字符串
result1 = re.findall('[a-z]{2,6}',string)
print("\n打印result1:")
print(result1) #打印:['python', 'java', 'php']
二、正则的贪婪与非贪婪
分析上例可以发现,本来最少匹配2个字符就已经可以识别字符串了,为什么会返回’Python’而不是’py’呢?因为这涉及到正则中的贪婪与非贪婪概念:
在默认情况下,Python倾向于贪婪的匹配方式,会尽可能的匹配更多的内容,所以此例中得到了完整的单词。
如果我们需要设置非贪婪匹配,需要借助’?’,具体代码如下:
#测试非贪婪匹配使用'?',效果同'[a-z]{2}'
result2 = re.findall('[a-z]{2,6}?',string)
print("\n打印result2:")
print(result2) #打印:['py', 'th', 'on', 'ja', 'va', 'ph']
三、更多数量词的使用
下面使用字符串:pythonStr = “pytho0python1pythonn2”来测试,使用正则来获取其中的’python’字段
1、”*”
匹配前面的子表达式0次或者无限多次 。例如,zo*能匹配“z”,也能匹配“zo”以及“zoo”。*等价于o{0,}
#代码示例如下:
result3 = re.findall('python*',pythonStr)
print("\n打印result3:")
print(result3) #打印:['pytho', 'python', 'pythonn']
2.”+”
匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
#代码示例如下:
result4 = re.findall('python+',pythonStr)
print("\n打印result4:")
print(result4) #打印:['python', 'pythonn']
3.”?”
匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”中的“do”。?等价于{0,1}。
#代码示例如下:
result5 = re.findall('python?',pythonStr)
print("\n打印result5:")
print(result5) #打印:['pytho', 'python', 'python']
注意:如果是一个范围’{}’后使用’?’, 此处的’?’就是转化非贪婪情况的使用,而非数量词的使用
result6 = re.findall('python{1,2}?',pythonStr)
print("\n打印result6:")
print(result6) #打印:['python', 'python’]
四、边界匹配符
边界匹配符可以设置被正则过滤段的范围,这里使用到了’^’与’$’,有关测试代码如下:
‘^’ : 从字符串开始匹配
‘$’ : 从字符串结尾处匹配
qqStr1 = "123456789"
qqStr2 = "1234567891" #超过9位的字符串
1.识别QQ号字符串,QQ的长度在7-9之间
result1_1 = re.findall('\d{7,9}',qqStr1)
result1_2 = re.findall('\d{7,9}',qqStr2)
print("\n打印result1:")
print(result1_1) #打印['123456789']
print(result1_2) #打印['123456789'],10位的也被匹配了
2.可以看到上面的正则由于没有添加边界,所以10位QQ号也被匹配了,这不符合要求,改进代码如下:
result2_1 = re.findall('^\d{7,9}$',qqStr1)
result2_2 = re.findall('^\d{7,9}$',qqStr2)
print("\n打印result2:")
print(result2_1) #打印['123456789']
print(result2_2) #打印[] 10位的QQ不符合要求,匹配无结果