python中使用正则表达式将所有符合条件的字段全部提取出来
后来问了同事以及进一步了解了正则的运行机制后,发现小括号()除了提取匹配的字符串,还有一个作用是用来捕获分组的,也就是说小括号中的内容匹配后会被存储起来,在调用的时候便会返回相应的值。而使用re.findall()时会将存储分组的值全部返回。 再举个例子会更加明白些,将上述pattern中的“((小便)|尿)”改为“((小便)|(尿))”,如: pattern = "[,;.,;。]+[^,;.,;。]*((小便)|(尿))+[^,;.,;。]*[,;.,;。]+" 使用re.findall()输出的结果为: [('尿', '', '尿'), ('小便', '小便', '')] 由上可知,“((小便)|(尿))”使用了三个“()”,于是便产生了三个分组,在最外围的第一个分组用于捕获“小便”或“尿”,原文中“小便”和“尿”都能匹配到,所以第一个位置两者都有;第二个分组是用来捕获“(小便)”的,所以第二个分组只存储“小便”;同理第三个分组用来捕获“(尿)”的,所以结果只存储了“尿”。 而我使用re.search()来输出分组结果: for line in lines: pattern = "[,;.,;。]+[^,;.,;。]*((小便)|(尿))+[^,;.,;。]*[,;.,;。]+" str = re.search(pattern, line) print(str.group(0)) print(str.group(1)) print(str.group(2)) print(str.group(3)) 结果为: ,无浮肿、泡沫尿, 尿 None 尿 group(1)、group(2)、group(3)分别与(‘尿', ‘', ‘尿')中对应的分组结果相同。但是这里的group(0)(或者说group(),两个意思完全一样)却不是“(‘尿', ‘', ‘尿')”;这里作者水平有限,不是很清楚原因,也就是说,当调用group(0)的时候,pattern中的()的意义并不再是捕获分组了,而是回到了原始的提取匹配字符串的意思上来了。 为了解决 pattern = "[,;.,;。]+[^,;.,;。]*[(小便)尿]+[^,;.,;。]*[,;.,;。]+" 会匹配到不想要的含有“大便”字符串的问题,通过使用非捕获分组(?:)便可以达到目的。 pattern = "[,;.,;。]?[^,;.,;。]*(?:小便|尿)[^,;.,;。]*[,;.,;。]" 此时便是匹配“小便”或者“尿”了;结果为: [',无浮肿、泡沫尿,', ',小便1-2小时1次,', '无尿痛、血尿。'] 注意上述结果,由于“,小便1-2小时1次,”和“无尿痛、血尿。”是紧接着的,而逗号已经被分配给了前者,所以后者便没有了逗号,这看起了有点像字符串的切片,被切走了就没了,所以这里在pattern中的第一个“[,;.,;。]”后面将“+”换成了“?”()意思的前面的字符出现0次或1次;当然更进一步可以优化为: pattern = "[,;.,;。]?[^,;.,;。]*(?:小便|尿).*?[,;.,;。]" 可以看到,将pattern中第二个“[^,;.,;。]”变为“.?” 上述虽然将所有子句全部匹配并输出了,但是相邻的两个子句还是分开输出的,仍旧没有达到我们想要的预期。于是对上述代码进行了改进: for line in lines: str = re.findall(pattern,line) print(str) 结果为: [',无浮肿、泡沫尿,', ',小便1-2小时1次,无尿痛、血尿。'] 而如果使用re.search(),也是可以达到预期的,代码如下: for line in lines: 结果为: ['无浮肿、泡沫尿,', '小便1-2小时1次,无尿痛、血尿。'] 到此这篇关于python中使用正则表达式将所有符合条件的字段全部提取出来的文章就介绍到这了,更多相关python 正则表达式提取字段内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! (编辑:晋中站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |