2017-10-25 4 views
3

私は、特定の形式でリストに読みたいテキストファイルを持っています。私が取得したいのですがPythonはregexによってファイルから行を読み込みます

27/08/15, 15:45 - text 
continue text 
continue text 2 
27/08/15, 16:10 - new text 
new text 2 
new text 3 
27/08/15, 19:55 - more text 

を::

27/08/15, 15:45 - text continue text continue text 2 
27/08/15, 16:10 - new text new text 2 new text 3 
27/08/15, 19:55 - more text 

私はときに私を分割したい

私は書いている:

with open('chat_history.txt', encoding='utf8') as f: 
    mylist = [line.rstrip('\n') for line in f] 

私は取得しています\nDD/MM/YY, HH:MM - 残念ながら、私は正規表現の専門家ではありません。私は試みた:

with open('chat_history.txt', encoding='utf8') as f: 
    mylist = [line.rstrip('\n'r'[\d\d/\d\d/\d\d - ]') for line in f] 

同じ結果を与えた。 2番目の考えでは、それがうまくいかない理由が理解できます。しかし、いくつかの助けを愛するだろう。

+1

理由だけ電流をテストしていませんそれが一致すれば、最初に改行を出力しますか? –

+0

ファイルの外観は? – Maroun

+0

ファイルは '27/08/15、15:45のようなものです - テキストの続きのテキストの続きのテキスト2 'ですが、私が行を読むと' 27/08/15、15:45 - テキスト\ nテキストを続けます\ nテキスト2 ' @ IgnacioVazquez-Abrams不要なデータはありません。私はすべてを使用しています、私はちょうどそれが正しいフォーマットであることを望みます – sheldonzy

答えて

1

確かに、これはトップ以上方法かもしれないと私は同じことを達成するために他の可能性があることを確認しています。新しいregex moduleを使用してここに私の解決策を(?(DEFINE)...)で提示したいと思います。最初のコードは、その後の説明:

import regex as re 

string = """ 
27/08/15, 15:45 - text 
continue text 
continue text 2 
27/08/15, 16:10 - new text 
new text 2 
new text 3 
27/08/15, 19:55 - more text 
""" 

rx = re.compile(r''' 
    (?(DEFINE) 
     (?P<date>\d{2}/\d{2}/\d{2},\ \d{2}:\d{2}) # the date format 
    ) 
    ^     # anchor, start of the line 
    (?&date)    # the previously defined format 
    (?:(?!^(?&date)).)+ # "not date" as long as possible 
''', re.M | re.X | re.S) 


entries = (m.group(0).replace('\n', ' ') for m in rx.finditer(string)) 
for entry in entries: 
    print(entry) 

この利回り:

27/08/15, 15:45 - text continue text continue text 2 
27/08/15, 16:10 - new text new text 2 new text 3 
27/08/15, 19:55 - more text 


基本的に、このアプローチは、間のテキストで区切られた日付のブロックを探します:

date 
text1 
text2 
date 
text3 
date 
text 

.. 。それらを一緒に置く。

date text1 text2 
date text3 
date text 
これは、負の先読みを介して達成される

date "match as long as there's no date in the next line" 

を次のように

「日付形式」を日付グループに定義され、その後構造です。その後、見つかったすべての改行は、スペースで置き換えられます(つまり、理解されます)。
明らかに、regexモジュールと(?(DEFINE)ブロックがなくても同じ結果を得ることができますが、一致と先読みで自分自身を繰り返す必要があります。
最後に、表現のためのa demo on regex101.comを参照してください。

+1

'\ n(?= \ d {2}/\ d {2}/\ d {2}、\ \ d {2}:\ d {2})で分割できません。 ' –

+0

@SebastianProske:うん。 – Jan

1
with open('chat_history.txt', encoding='utf8') as f: 
    l = [line.rstrip('\n').replace('\n', ' ') for line in f] 

print(l) 
1

私のソリューションは、Jan'sよりも簡単な正規表現を使用しています。正規表現を使用しているコードは少し冗長です。

まず、入力ファイル:

$ cat -e chat_history.txt 
27/08/15, 15:45 - text$ 
continue text$ 
continue text 2$ 
27/08/15, 16:10 - new text$ 
new text 2$ 
new text 3$ 
27/08/15, 19:55 - more text$ 

コード:

import re 

date_time_regex = re.compile(r'^\d{2}/\d{2}/\d{2}, \d{2}:\d{2} - .*') 

with open('chat_history.txt', encoding='utf8') as f: 
    first_date = True 
    for line in f: 
     line = line.rstrip('\n') 

     if date_time_regex.match(line): 
      if not first_date: 
       # Print a newline character before printing a date 
       # if it is not the first date. 
       print() 
      else: 
       first_date = False 
     else: 
      # Print a separator, without a newline character. 
      print(' ', end='') 

     # Print the original line, without a newline character. 
     print(line, end='') 

# Print the last newline character. 
print() 

コードを実行する(および末尾のスペースを示さない):

$ python3 chat.py | cat -e 
27/08/15, 15:45 - text continue text continue text 2$ 
27/08/15, 16:10 - new text new text 2 new text 3$ 
27/08/15, 19:55 - more text$ 
関連する問題