我是靠谱客的博主 坦率热狗,最近开发中收集的这篇文章主要介绍Python 正则是否存在前向贪婪匹配呢?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

场景描述

由于项目的某一些应用场景出现了如下的需求:

A: str = “ABCABABCABABC”

B: 将其中ABC都抠出来 

猛一看,这还不easy呢? 直接    ABC匹配不就出来了吗?

str = "ABCABABCABABC"
res = re.findall(r'ABC', str, re.M)

这结果不就出来了吗?

可是难就难在这边,这边的ABC并非真实的字母,而是一个泛指 。具体的str参见如下描述:

str1 = "a:bc123cdfddd1 d32sfdfds2332fsd1 n data:dsafdsfssdfsdnalert ===> virusn" 
"a:bc123cdfdddd2 32sfdfds2332fsd1 n data:dsafdsfssdfsd end222end!!!!n" 
"a:bc123cdfdddd3 32sfdfds2332fsd1 n data:dsafdsfssdfsdnalert===> no virusn" 
"a:bc123cdfdddd3 32sfdfds2332fsd1 n data:dsafdsfssdfsdnalert===> no virusn" 
"a:bc123cdfdddd2 32sfdfds2332fsd1 n data:dsafdsfssdfsd end33333end!!!n"

要求:

1、我们忽略'n',可以看到我们这边暂时分为了五行,我们要做到的事: 匹配第一、三、四行数据 

2、扣除 一三四行中后面的ddd1、ddd3以及与之对应的 alert结果 no virus

 

实战分析

既然题目已经给出了, 那么我们就来做吧。 对于正则,我想大部分人已经非常熟悉了。

首先,我们必须忽略'n', 那么我们必须使用re库中的S,表示忽略n换行符。  

sp = re.findall("a[:].*?data[:].*?alert.*?n", str1, re.S)
print sp
for i in range(len(sp)):
print sp[i]

这是我一开始给出的正则表达式,可惜得到的结果不尽人意:

a:bc123cdfddd1 d32sfdfds2332fsd1
data:dsafdsfssdfsd
alert ===> virus
a:bc123cdfdddd2 32sfdfds2332fsd1
data:dsafdsfssdfsd end222end!!!!
a:bc123cdfdddd3 32sfdfds2332fsd1
data:dsafdsfssdfsd
alert===> no virus
a:bc123cdfdddd3 32sfdfds2332fsd1
data:dsafdsfssdfsd
alert===> no virus

我们可以看到,结果分割出来  起始 和结束都没有问题,但是中间 类似于“ABABC”却被匹配上了。这不是我们想要的。

 

正则的前向贪婪匹配

我们都知道,正则有自己的贪婪模式,可以向后匹配最近的字段。那么我们能不能根据alert字段匹配前面最近的AB呢?

str2 = "00000aaaaa111111aaa00000bbbbb11111"
res2 = re.findall(r'(?<=0)(?!0)w+?(?=1)', str2)
print res2
#结果
['aaaaa', 'bbbbb']

可惜呢,找了全网 基本都没有我们想要的结果。于是乎 这条路基本就算走死了。

如果以后,发现了 再回来!!!!! 

 

 

最终解决

似乎,我们想要的都不是我们期望的,那行吧,既然前向走不通,那就最简单的方式吧。

将所有 

n data
==》 data
n alert ==》 alert

那么我们的串将变为:

str1 = "a:bc123cdfddd1 d32sfdfds2332fsd1
data:dsafdsfssdfsd alert ===> virusn" 
"a:bc123cdfdddd2 32sfdfds2332fsd1
data:dsafdsfssdfsd end222end!!!!n" 
"a:bc123cdfdddd3 32sfdfds2332fsd1
data:dsafdsfssdfsd alert===> no virusn" 
"a:bc123cdfdddd3 32sfdfds2332fsd1
data:dsafdsfssdfsd alert===> no virusn" 
"a:bc123cdfdddd2 32sfdfds2332fsd1
data:dsafdsfssdfsd end33333end!!!n"

结果却依然没有改变ABABC这样的问题,

a:bc123cdfddd1 d32sfdfds2332fsd1
data:dsafdsfssdfsd alert ===> virus
a:bc123cdfdddd2 32sfdfds2332fsd1
data:dsafdsfssdfsd end222end!!!!
a:bc123cdfdddd3 32sfdfds2332fsd1
data:dsafdsfssdfsd alert===> no virus
a:bc123cdfdddd3 32sfdfds2332fsd1
data:dsafdsfssdfsd alert===> no virus

但是我们接着对上述结果 进行再匹配(原先的中间间隔换行不太好搞) 注意这边使用的re.M 不写或者re.S都会出错!!!

res = re.findall(r'a:.*?\(.*?) .*?===>(.*?)n', str1, re.M)
print res
#结果
[('ddd1', ' virus'), ('ddd3', ' no virus'), ('ddd3', ' no virus')]

 

总结下吧

对于这种多换行的正则匹配,没有好的办法 可以替换 换行,最后在替换回来的办法 进行匹配检索!!!!

 

最后附上完整代码 练习使用!

# encoding:utf-8
import re
str1 = "a:bc123cdfddd1 d32sfdfds2332fsd1
data:dsafdsfssdfsd alert ===> virusn" 
"a:bc123cdfdddd2 32sfdfds2332fsd1
data:dsafdsfssdfsd end222end!!!!n" 
"a:bc123cdfdddd3 32sfdfds2332fsd1
data:dsafdsfssdfsd alert===> no virusn" 
"a:bc123cdfdddd3 32sfdfds2332fsd1
data:dsafdsfssdfsd alert===> no virusn" 
"a:bc123cdfdddd2 32sfdfds2332fsd1
data:dsafdsfssdfsd end33333end!!!n"
sp = re.findall("a[:].*?data[:].*?alert.*?n", str1, re.S)
print sp
for i in range(len(sp)):
print sp[i]
str2 = "00000aaaaa111111aaa00000bbbbb11111"
res2 = re.findall(r'(?<=0)(?!0)w+?(?=1)', str2)
print "11111"
print res2
res = re.findall(r'a:.*?\(.*?) .*?===>(.*?)n', str1, re.M)
print res
str = "ABCABABCABABC"
res = re.findall(r'ABC', str, re.M)
print res

 

最后

以上就是坦率热狗为你收集整理的Python 正则是否存在前向贪婪匹配呢?的全部内容,希望文章能够帮你解决Python 正则是否存在前向贪婪匹配呢?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(53)

评论列表共有 0 条评论

立即
投稿
返回
顶部