Pythonでコーテーションに囲まれた部分はSplitの対象外にする関数を作った

PythonでApacheのアクセスログの解析スクリプトを走らせてみようと思ったのだけれども、
Apacheのログはスペース区切りなのに、ユーザーエージェントなどでスペースが入るので正しく区切ることができない。

CSVやTSVなどで、コーテーションに囲まれている内部のカンマやタブでは区切らないSplitは無いものだろうか…

なさそうなので作ってみた。
※連続二個表記や\マークでエスケープされたコーテーションは文字列として扱う機能は無い。

import re

def Split(s ,sep ):
    kakkoDic = {'"':'"','\'':'\'','[':']'}
    kakkoKeys = kakkoDic.keys()

    reslist = []
    ary = s.split(sep)

    targetstr = ary[0]

    if len(targetstr) >= 1 and targetstr[0] in kakkoKeys:

        p = re.compile(kakkoDic[targetstr[0]]+'$')
        joinlist = []
        num = 0
        for s in ary:
            num = num + 1
            joinlist.append(s)
            if len(ary) <= 1 or p.search(s) != None:
                s2 = joinlist[len(joinlist) - 1]
                joinlist[len(joinlist)-1] = s2[0:len(s2) ]
                break
        c = sep.join(joinlist)
        c = c[1:len(c) -1 ]
        ary = ary[num:len(ary)]
        reslist.append(c)
    else:
         reslist.append(ary[0])
         ary.pop(0)

    if ary:
        reslist = reslist +  Split(sep.join(ary),sep)
    return reslist

if __name__ == '__main__':
    s = 'one,tow,tree,four,five,,"","hello,world","ko,nn,ni,chi,wa",,,,'
    print(s)
    print(Split(s,","))

CentOSで動かすことを考えて、2.7系で動かしている。
if __name__ == ‘__main__’:の部分(なんていうのこれメインメソッドでいいの?)もサンプルとして付属しておいて
実行すれば動作確認ができるようになっとります。

実行結果はこんな感じ、ちゃんと動いている見たい。

one,tow,tree,four,five,,””,”hello,world”,”ko,nn,ni,chi,wa”,,,,
[‘one’, ‘tow’, ‘tree’, ‘four’, ‘five’, ”, ”, ‘hello,world’, ‘ko,nn,ni,chi,wa’, ”, ”, ”, ”]

追記
ちょっとバグ発見したので修正しました。

解説

Splitメソッドの第一引数は文字列、第二引数は区切る場所を示す文字

Splitメソッド内では、区切り文字で区切ったリストから一番先頭の文字列の一文字目を見て、
もし括弧とかコーテーションがあれば、おしりに対応する括弧を持つ要素までの内容を再結合する。
再結合した物を結果用のリストにアペンド

もし、リストの一番最初の文字列の一文字目にコーテーションなどがない場合は、それを結果用リストにアペンド

今評価した部分以外の配列を再結合して、Splitメソッドを再帰呼出しして、帰ってきたリストと結果リストを結合して戻す。

わかりやすくするために、string.splitやJoinを多用して再帰呼出しも使っているので恐らくだいぶ遅いと思う。

まあでも、これでちゃんと動きそうなので、これを利用してApacheのアクセスログ解析スクリプトを作っておこう。

スポンサードリンク

関連コンテンツ