正则表达式非常强大,但是也有做不到的事情:
正则表达式的只能按照顺序就是从前往后找
但是你如果已经找了前面一段,就绝不可能回头重新找。举例说明:
mystr="abcdeffg"
kk=re.findall('abc|cde',mystr)
print(kk)
#结果是['abc']
# 你可能觉得cde存在啊?怎么可能找不出来,那是因为程序找了abc,就不可能回头从c找起!
但是如果你这么找
kk=re.findall('abc|effg',mystr)
print(kk)
#['abc', 'effg']
#程序可以找到所有相关的内容
2.正则式的模式
正则式的模式非常重要。
match只能从头匹配,找到了就结束
search也只是从字符串中在找到匹配的模式,找到一个就结束。
而findall函数和sub函数(不限次数)则完全不同,非要找完整个字符串才能罢休。
re.I表示将忽略大小写
re.M表示 "^" 匹配字符串的开始和字符串中每行的开始。同样的, $ 元字符匹配字符串结尾和字符串中每行的结尾(直接在每个换行之前)
所以必须选择正确的正则式模式
3.善用分组
在一个字符串中使用分组是非常常见的事情,但是如果你既使用了分组也使用了|模式来定义不同模式的分组。事情就变了。
hhh='''8123 171.38.85.122 高匿 HTTP 1087天 18-11-0601:50
45.68.172.79 Https 678 高匿 2天 18-11-0601:50
'''
#想找出对应的ip地址和端口号。用分组再好不过了。但是不同模式的不同分组事情就不是一回事了。
pattern=re.compile('(\d{4,5})\s(\d+\.\d+\.\d+\.\d+)|(\d+\.\d+\.\d+\.\d+).*(\d{3,5})\s' ,)
IP_port=re.findall(pattern,hhh)
print(IP_port)
#[('8123', '171.38.85.122', '', ''), ('', '', '45.68.172.79', '678')]
#这样取出来的格式太难处理。
#我能想到的就是先把不用模式的相关信息取出来,再进一步的做处理。
pattern=re.compile('\d{4,5}\s\d+\.\d+\.\d+\.\d+|\d+\.\d+\.\d+\.\d+.*\d{3,5}\s')
IP_port=re.findall(pattern,hhh)
print(IP_port)
#['8123 171.38.85.122', '45.68.172.79 Https 678\n']
#对取出的列表再用函数做处理就比较简单。
3.中文在正则式中的表示
\w表示[a-z0-9_]这个相信大家都非常清楚。但是\w能表示中文吗?答案是\w包括中文但是不能将中文从字符串和数字中区分出来。
网络上早就有了正则[u0391-uFFE5]就可以表示中文。但是在实际的应用中我们需要取出中文字符里面的部分内容,而这个办法就无能为力。所以一般我们用零宽断言和()和[]来取出特定的中文字符串。
4.sub的应用
一般我们用正则都是用来抓取数据,但是换个思路,我们也可以用来剔除数据。
而sub是用来剔除异常数据最好的工具。
mystr="请问jfakj8*%4^&8&0什么姓名张三%976GH对吗$@$%^"
filter1=re.sub('\W','',mystr)
print(filter1)
#请问jfakj8480什么姓名张三976GH对吗
filter2=re.sub('\d+','',filter1)
print(filter2)
#请问jfakj什么姓名张三GH对吗
#所以我们可以使用sub来实现层层过滤
4.\b,$,^,\B定位符的使用
\b是单词和符号的边界,而并不是单纯的指空格。
str1=#wang@
str2=wangquan
定位符号就是为了分辨上面这两种情况而出现的。第一个字符wang两边都是\b;而第二个字符中wang后面也是字符,那么wang后面是\B
5.分组数据的改造:
分组数据的改造可以代替很多函数的功能。也方便的多。
a="dfha.txt"
bb=re.sub(r'(\w+)(.txt)',r'\1_conv\2',a)
print(bb)
#结果是dfha_conv.txt
#如果你喜欢,可以做出更多更复杂的改造。
以上是我想到的几点。欢迎大家提出意见并完善。仓促之间如有错漏希望斧正,谢谢大家。[email protected]