用python正則表達式提取字符串

在平常工做中常常碰見在文本中提取特定位置字符串的需求.python的正則性能好,很適合作這類字符串的提取,這裏講一下提取的技巧,正則表達式的基礎知識就不說了,有興趣的能夠看re的教程. 提取通常分兩種狀況,一種是提取在文本中提取單個位置的字符串,另外一種是提取連續多個位置的字符串.日誌分析會遇到這種狀況.下面我會分別講一下對應的方法:python

1. 單個位置的字符串提取


這種狀況咱們可使用(.+?)這個正則表達式來提取. 舉例,一個字符串"a123b",若是咱們想提取ab之間的值123,可使用findall配合正則表達式,這樣會返回一個包含因此符合狀況的list,代碼以下:web

import re
str = "a123b"
print re.findall(r"a(.+?)b",str)#
輸出['123']

 

 

1.1貪婪和非貪婪匹配


若是咱們有一個字符串」a123b456b」,若是咱們想匹配a和最後一個b之間的全部值而非a和第一個出現的b之間的值,能夠用?來控制正則貪婪和非貪婪匹配的狀況. 代碼以下:正則表達式

import re
str = "a123b456b"

print re.findall(r"a(.+?)b", str)
#輸出['123']#?控制只匹配0或1個,因此只會輸出和最近的b之間的匹配狀況

print re.findall(r"a(.+)b", str)
#輸出['123b456']

print re.findall(r"a(.*)b", str)
#輸出['123b456']

 

 

1.2多行匹配


若是你要多行匹配,那麼須要加上re.Sre.M標誌. 加上re.S後, .將會匹配換行符,默認.不會匹配換行符. 代碼以下:api

str = "a23b\na34b"

re.findall(r"a(\d+)b.+a(\d+)b", str)
#輸出[]
#由於不能處理str中間有\n換行的狀況

re.findall(r"a(\d+)b.+a(\d+)b", str, re.S)
#s輸出[('23', '34')]

 

 

加上re.M後,^$標誌將會匹配每一行,默認^$只會匹配第一行. 代碼以下:性能

str = "a23b\na34b"

re.findall(r"^a(\d+)b", str)
#輸出['23']

re.findall(r"^a(\d+)b", str, re.M)
#輸出['23', '34']

 

 

2. 連續多個位置的字符串提取


這種狀況咱們可使用(?P<name>…)這個正則表達式來提取. 舉例,若是咱們有一行webserver的access日誌:'192.168.0.1 25/Oct/2012:14:46:34 "GET /api HTTP/1.1" 200 44 "http://abc.com/search" "Mozilla/5.0"',咱們想提取這行日誌裏面全部的內容,能夠寫多個(?P<name>expr)來提取,其中name能夠更改成你爲該位置字符串命名的變量,expr改爲提取位置的正則便可. 代碼以下:spa

import re
line ='192.168.0.1 25/Oct/2012:14:46:34 "GET /api HTTP/1.1" 200 44 "http://abc.com/search" 
"Mozilla/5.0"'
reg = re.compile('^(?P<remote_ip>[^ ]*) (?P<date>[^ ]*) "(?P<request>[^"]*)" 
(?P<status>[^ ]*) (?P<size>[^ ]*) "(?P<referrer>[^"]*)" "(?P<user_agent>[^"]*)"')
regMatch = reg.match(line)
linebits = regMatch.groupdict()
print linebits
for k, v in linebits.items() :
    print k+": "+v

 

 

輸出的結果爲:日誌

status: 200
referrer:  
request: GET /api HTTP/1.1
user_agent: Mozilla/5.0
date: 25/Oct/2012:14:46:34size: 44
remote_ip: 192.168.0.1

 

 

 

相關文章
相關標籤/搜索