2017-03-20 9 views
1

正規表現を使ってログファイルを解析しています。 ログの例:Python正規表現の短縮化

<teststep timestamp="12040.310594" level="0" type="user" ident="1.2" result="pass">Signal STATUS_GET_VALUE response time Ok,\nSignal response time: 0.000000 [ms] \nSignal response time limit set: 100.000000 [ms]</teststep> 

私はタイムスタンプ信号応答時間を抽出する必要があります。

この問題に対する私の解決策:

with open('report.xml') as f: 
for line in f: 
    if 'Signal response time: ' in line: 
     timeStampL = re.findall('timestamp="\d*.\d*"', line) 
     responseTimeL = re.findall('Signal response time: \d*.\d*', 
            line, re.IGNORECASE) 
     timeStamp = float(re.findall('\d+.\d+', timeStampL[0])[0]) 
     responseTime = float(re.findall('\d+.\d+', responseTimeL[0])[0]) 

私はこれが最短とこのデータを取得するための最良の方法ではないことを確信しています。 より良いアプローチを提案しますか?

+7

お取置き....正規表現でXML/HTMLを処理しません。ここでは、ペイロードのBeautifulSoup、XPathの、ElementTreeの、... –

+0

@WillemVanOnsemがはるかに使い、しかし、構造化されたXMLではありません。だからそれは不合理ではないようです。 – pvg

+0

より良い方法は、同じ行を何度も何度も繰り返してマッチさせることではありません。 1つの正規表現はあなたが興味を持っていると思われる2つの値を簡単に引き出すことができるので、その正規表現を書いてください。または、動作していてパフォーマンスの問題でない場合は、そのまま使用してください。 – pvg

答えて

2

あなたはあなたのデータにsplit()を使用して、0.000000 [ms]だけを得ることができます。

コード:

from bs4 import BeautifulSoup 

html_code = '<teststep timestamp="12040.310594" level="0" type="user" ident="1.2" result="pass">Signal STATUS_GET_VALUE response time Ok,\nSignal response time: 0.000000 [ms] \nSignal response time limit set: 100.000000 [ms]</teststep>' 

soup = BeautifulSoup(html_code, "html.parser") 

for test in soup.find_all('teststep'): 
    print(test.get('timestamp')) 
    print(test.text.split("\n")[1].split(":")[1].strip()) 

出力:

12040.310594 
0.000000 [ms] 

P.s:あなたは、この変更によって0.000000 [ms][ms]を削除することができます

0をこれに

test.text.split("\n")[1].split(":")[1].strip().replace(" [ms]", "")

1

希望の結果を得る別の方法は、BeautifulSoupのようなXML/HTMLパーサーを使用して、要素を見つけるためにtimestamp属性を取得することです(BeautifulSoupで要素を辞書として扱うことができます属性)と、正規表現で「信号応答時間」を抽出:テキスト値Signal STATUS_GET_VALUE response time Ok,\nSignal response time: 0.000000 [ms] \nSignal response time limit set: 100.000000 [ms]\n SEPARが付属していますので

:私たちは、このようなBeautifulSoupを使用して属性値や要素のテキストを抽出することができ

In [1]: import re 

In [2]: from bs4 import BeautifulSoup 

In [3]: data = """<teststep timestamp="12040.310594" level="0" type="user" ident="1.2" result="pas 
    ...: s">Signal STATUS_GET_VALUE response time Ok,\nSignal response time: 0.000000 [ms] \nSignal 
    ...: response time limit set: 100.000000 [ms]</teststep>""" 

In [4]: soup = BeautifulSoup(data, "html.parser") 

In [5]: pattern = re.compile(r"Signal response time: ([0-9.]+)") 

In [6]: elm = soup.find("teststep", text=pattern) 

In [7]: print(elm["timestamp"], pattern.search(elm.get_text()).group(1)) 
12040.310594 0.000000