2017-12-21 15 views
0

この質問は以前に聞かれたかもしれませんが、私の状況と一致しません。私はすでに彼らのほとんどを通過しましたが、解決策のどれもが助けていません。変数番号の間に特定の行を抽出します。 Pythonのテキストファイルからの行

ここに問題があります。私は大量の行を含むテキストファイルを持っています。ここで
は、ファイルのサンプルです:

yyyyyy=xxxx 
yyyyyy=xxxxxxxx 

Sun Oct 22 15:19:23 PDT 2017 
calling sequenc node 

++ entering node aaa (  ) 
Sun Oct 22 15:19:23 PDT 2017 
lines xxxxxxxx 
calling wroot.bat 

++ entering node bbb (xxx  ) 
Sun Oct 22 15:19:23 PDT 2017 
xxxxxxxxxxxxxx 
calling bsod.bat 
xaaaaa 
bbbbb 
tttttt 
bbb completed successfully 
-- exiting node bbb 

++ entering node ccc (yyyy  ) 
Sun Oct 22 15:19:35 PDT 2017 
xxxxxxxxxxxxxxxxx 
calling wpretest.bat 

今、私は正常に完了ラインより上にある行に(付属)を呼び出す部分から行を抽出したいです。また、++で始まる部分だけを抽出したい。のない。通話後の回線は異なります。空白、それに続く2行以上の行があります。それに続く行がない場合、私は呼び出し側の行を抽出したいだけです。次の行で正常に完了した場合は、1つの呼び出し元行を抽出します。そして、発呼ラインの間に他の回線があり、正常に完了した場合は、それらのすべてを抽出したいと思います。あなたはregexこれをしたい場合は

calling wroot.bat 
calling bsod.bat, 
xaaaaa, 
bbbbb, 
tttttt 
calling wpretest.bat 
+1

試したコードとサンプルテキストを含めてください –

+0

サンプルはどこですか?入力と期待される出力を持つ詳細な例を教えてください。 – Allan

+0

申し訳ありません。私の質問を編集しました。 –

答えて

1

:ここ

は、ここで(動作していないようでした)私はあまりにも正規表現と一緒にしようとしているコード

with open('myfile.txt','r') as log: 
    for line in log: 

     match = re.search(node_name_pattern, line) 
     if line.startswith('++') and match:   
      node_name.append(match.group()) 
      nn=match.group() 
     match2 = re.search(node_parameter, line) 
     if line.startswith('++') and match2: 
      parameter.append(match2.group()) 
      start_time.append(log.next().strip()) 
      features.append(log.next().strip()) 
     if "calling" in line : 
       content.append(line.strip()) 

が予想される出力です動作するはず:

に結果の
r'(?<=\n)calling.*?(?=\n[^\n]*completed succ[^\n]*\n|\n\+\+|\s*\Z)' 

だから、あなたはそれで遊ぶことができます正規表現

を破壊

>>> bla = open('bla').read() 
>>> re.findall(r'(?<=\n)calling.*?(?=\n[^\n]*completed succ[^\n]*\n|\n\+\+|\s*\Z)',bla,re.DOTALL) 
['calling sequenc node\n', 'calling wroot.bat \n', 'calling bsod.bat \nxaaaaa\nbbbbb\ntttttt', 'calling wpretest.bat'] 

  1. (?<=\n)calling - それはすぐに改行が続く場合、「呼び出す」という単語を探します。

  2. .*は、あなたが(|手段または)の(?=...|...|...) 1を打つまで、非欲張って何
  3. に一致するに進みます。 \n[^\n]*completed succ[^\n]*\n「完了したsucc」を含む行。これは本質的に改行であり、 "succ"が完了するまで、改行以外の多くの文字が必要であり、さらに多くの文字があり、最終的には改行されます。 completed succ部分でおそらく終わる可能性があります。この行の残りの部分にマッチすることは気にしないので、今私はそれについて考えています。

    b。 \n\+\+ "++"で始まる改行。

    c。 \s*\Z文字列全体の末尾までの空白文字(\ n、 ""、\ tなど)の量は、\Zです。たぶん行だけの場合には、callingで始まる場合inside==Falseていることを確認し、エラー

    res = [] 
    inside = False 
    with open('bla') as bla: 
        for line in bla: 
         if inside: 
          if line.startswith('++') or "completed successfully" in line: 
           inside = False 
          else: 
           res[-1].append(line)    
         elif line.startswith("calling"): 
          res.append([line]) 
          inside = True 
    

私はちょうどのようなループ、何かを使用して検討します。

+0

試してみましたが、役に立たなかった。それは私に2つの連続した呼び出しの行がある行だけを与えます。 –

+0

@ImdadulChoudhury私は最後の行のコールと予想されるアウトプットのコールを一致させたいと思っていました。私はあなたが2つの連続した呼び出しを意味することで確信していませんが、今は期待される出力が私のものと一致します。 – kabanus

+0

連続して私は出力が私に "呼び出し"一緒に始まる2行がある行を与えていることを意味した。 –

関連する問題