2017-01-25 8 views
0

文字列を辞書に変換する必要があります。より具体的には、Auditdメッセージを辞書に解析する必要があります。 EX: 文字列:ここ文字列を再帰と正規表現でPython辞書に変換

msg=audit(123.123:123): pid=2514 uid=1000 auid=1000 ses=3 subj=random_ex:random_ex:random_ex:d3-d3:w0.c12 30 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="lemoney" exe="/usr/bin/sudo" hostname=? a ddr=? terminal=/dev/pts/0 res=success' 

は、いくつかの交互ます:

私が望むものを
msg=audit(1234902.147:88): pid=254 uid=1000 auid=1000 ses=3 subj=random_ex:random_ex:random_ex:d3-d3:w0.c12 30 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="lemoney" exe="/usr/bin/grep" hostname=? a ddr=? terminal=/dev/pts/0 res=success' 

msg=audit(432787023.324:77): pid=1254 uid=1000 auid=1000 ses=3 subj=random_ex:random_ex:random_ex:d3-d3:w0.c12 30 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="lemoney" exe="/usr/bin/tail" hostname=? a ddr=? terminal=/dev/pts/0 res=success' 

は次のとおりです。

{ 
    msg: 'audit(...', 
    pid: ..., 
    uid: ..., 
    mess: { 
    op: PAM..., 
    grantors=pam_unix... 
    } 
} 

私は本当に私が必要と知っているこの上で私の頭を打っています正規表現と再帰的にする必要がありますが、私はいくつかの助けに非常に感謝します。

+0

はい。それぞれが個別のエントリです – lemoney

答えて

1

あります(一部の正規表現の助けを借りて)行く:

import re 

string = """ 
msg=audit(1234902.147:88): pid=254 uid=1000 auid=1000 ses=3 subj=random_ex:random_ex:random_ex:d3-d3:w0.c12 30 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="lemoney" exe="/usr/bin/grep" hostname=? a ddr=? terminal=/dev/pts/0 res=success' 

msg=audit(432787023.324:77): pid=1254 uid=1000 auid=1000 ses=3 subj=random_ex:random_ex:random_ex:d3-d3:w0.c12 30 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="lemoney" exe="/usr/bin/tail" hostname=? a ddr=? terminal=/dev/pts/0 res=success' 
""" 

# lines regex 
entries = re.compile(r'^msg=.+', re.MULTILINE) 

# outer regex 
rx = re.compile(""" 
    ((\w+)='([^']+)') # longer group 
    |    # or 
    (\w+=\S+)  # single items 
    """, re.VERBOSE) 

# inner regex 
ry = re.compile("(\w+)=(\S+)") 

for entry in entries.finditer(string): 
    result = dict() 
    for match in rx.finditer(entry.group(0)): 
    try: 
     key, value = match.group(4).split('=') 
     result[key] = value 
    except: 
     #key = match.group(2) 

     inner = dict() 
     for m in ry.finditer(match.group(3)): 
     inner[m.group(1)] = m.group(2) 

     result["mess"] = inner 

    print(result) 

a demo on ideone.comを参照してください。ここで

+0

ニース。大変ありがとうございました。前にforループを扱っていた – lemoney

+0

最初のmsg値(123.123:123の値)が上書きされます。私はリファクタリングしていますが、どんな助けもありがとう – lemoney

0

は可能ですが、何の正規表現は、これを作る過程で殺されなかった。

import shlex 
from collections import OrderedDict 

def split_on_equals_to_dict(string_to_split): 
    split_dict = OrderedDict() 
    for i, item in enumerate(shlex.split(string_to_split)): 
     number_of_equals = item.count('=') 
     if number_of_equals == 0: 
      split_dict[item] = None 
     elif number_of_equals == 1: 
      split_dict.update(dict([item.split('=')])) 
     else: 
      tag, value = tuple(item.split('=', 1)) 
      split_dict[tag] = split_on_equals_to_dict(value) 
    return split_dict 

log_str="""audit(123.123:123): pid=2514 uid=1000 auid=1000 ses=3 subj=random_ex:random_ex:random_ex:d3-d3:w0.c12 30 msg='op=PAM:accounting grantors=pam_unix,pam_localuser acct="lemoney" exe="/usr/bin/sudo" hostname=? a ddr=? terminal=/dev/pts/0 res=success'""" 
log_dict = split_on_equals_to_dict(log_str) 

た文字列でいくつかのあいまいさがあります。私はこれをOrderedDictを使って処理しました。

関連する問題