Python 正則是否存在前向貪婪匹配呢?
場景描述
由於專案的某一些應用場景出現瞭如下的需求:
A: str = “ABCABABCABABC”
B: 將其中ABC都摳出來
猛一看,這還不easy呢? 直接 ABC匹配不就出來了嗎?
str = "ABCABABCABABC"
res = re.findall(r'ABC', str, re.M)
這結果不就出來了嗎?
可是難就難在這邊,這邊的ABC並非真實的字母,而是一個泛指 。具體的str參見如下描述:
str1 = "a:bc123cdf\ddd1 d32sfdfds2332fsd1 \n data:dsafdsfssdfsd\nalert ===> virus\n" \
"a:bc123cdfd\ddd2 32sfdfds2332fsd1 \n data:dsafdsfssdfsd end222end!!!!\n" \
"a:bc123cdfd\ddd3 32sfdfds2332fsd1 \n data:dsafdsfssdfsd\nalert===> no virus\n" \
"a:bc123cdfd\ddd3 32sfdfds2332fsd1 \n data:dsafdsfssdfsd\nalert===> no virus\n" \
"a:bc123cdfd\ddd2 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:bc123cdf\ddd1 d32sfdfds2332fsd1
data:dsafdsfssdfsd
alert ===> virus
a:bc123cdfd\ddd2 32sfdfds2332fsd1
data:dsafdsfssdfsd end222end!!!!
a:bc123cdfd\ddd3 32sfdfds2332fsd1
data:dsafdsfssdfsd
alert===> no virus
a:bc123cdfd\ddd3 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:bc123cdf\ddd1 d32sfdfds2332fsd1 data:dsafdsfssdfsd alert ===> virus\n" \
"a:bc123cdfd\ddd2 32sfdfds2332fsd1 data:dsafdsfssdfsd end222end!!!!\n" \
"a:bc123cdfd\ddd3 32sfdfds2332fsd1 data:dsafdsfssdfsd alert===> no virus\n" \
"a:bc123cdfd\ddd3 32sfdfds2332fsd1 data:dsafdsfssdfsd alert===> no virus\n" \
"a:bc123cdfd\ddd2 32sfdfds2332fsd1 data:dsafdsfssdfsd end33333end!!!\n"
結果卻依然沒有改變ABABC這樣的問題,
a:bc123cdf\ddd1 d32sfdfds2332fsd1 data:dsafdsfssdfsd alert ===> virus
a:bc123cdfd\ddd2 32sfdfds2332fsd1 data:dsafdsfssdfsd end222end!!!!
a:bc123cdfd\ddd3 32sfdfds2332fsd1 data:dsafdsfssdfsd alert===> no virus
a:bc123cdfd\ddd3 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:bc123cdf\ddd1 d32sfdfds2332fsd1 data:dsafdsfssdfsd alert ===> virus\n" \
"a:bc123cdfd\ddd2 32sfdfds2332fsd1 data:dsafdsfssdfsd end222end!!!!\n" \
"a:bc123cdfd\ddd3 32sfdfds2332fsd1 data:dsafdsfssdfsd alert===> no virus\n" \
"a:bc123cdfd\ddd3 32sfdfds2332fsd1 data:dsafdsfssdfsd alert===> no virus\n" \
"a:bc123cdfd\ddd2 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 RE庫的貪婪匹配和最小匹配Python
- 正規表示式:貪婪模式與非貪婪模式模式
- 正規表示式貪婪模式與非貪婪模式模式
- 【正規表示式系列】貪婪與非貪婪模式模式
- 正規表示式 貪婪模式模式
- 11.一個正規表示式案例讓你馬上明白貪婪匹配與禁止貪婪! 超級實用!
- Java 正規表示式匹配模式(貪婪型、勉強型、佔有型)Java模式
- Python正則匹配中文Python
- php 正則如何匹配手機號碼呢?PHP
- python的re正則匹配Python
- 正則匹配規則2
- Python 中的貪婪排名演算法Python演算法
- PHP 正則匹配中文PHP
- python正則一些簡單匹配Python
- Logstash之Grok正則匹配,讓正則進階!
- Java處理正則匹配卡死(正則回溯問題)Java
- 貪婪演算法回顧演算法
- Laravel redis 正則匹配keysLaravelRedis
- 正則匹配方法及示例
- 07 nginx Location之正則匹配Nginx
- oracle10g的正則規則匹配Oracle
- shell正則匹配捕獲引用進行IP匹配
- 貪心演算法(貪婪演算法,greedy algorithm)演算法Go
- python爬蟲中使用正則match( )方法匹配目標Python爬蟲
- Python-網頁轉義字元及正則全文匹配Python網頁字元
- java中url正則regex匹配Java
- php正則匹配所有違規字元PHP字元
- Linux篇---Grep和正則匹配Linux
- 正則匹配指定字元之前的字串字元字串
- JAVA 正規表示式的三種模式: 貪婪, 勉強和佔有的討論Java模式
- iOS擷取特定的字串(正則匹配)iOS字串
- phputf-8編碼正則匹配中文PHP
- VIM-灰常有用的正則匹配
- 「python」正則Python
- Epic 大戰谷歌蘋果,未必只因貪婪谷歌蘋果
- python 正規表示式匹配Python
- 學習筆記——正則匹配方法整理筆記
- 探究js正則匹配方法:match和execJS