2017-05-07 9 views
3

私はこの形式のテキストファイルがあります。内容の一部に改行があるテキストファイルを読むにはどうすればよいですか?

06/01/2016, 10:40 pm - abcde 
07/01/2016, 12:04 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 6:14 pm - abcde 

fghe 
07/01/2016, 6:20 pm - abcde 
07/01/2016, 7:58 pm - abcde 

fghe 

ijkl 
07/01/2016, 7:58 pm - abcde 

をあなたはすべての行が改行で区切られていることがわかりますが、一部の行の内容は、それらの中に改行を持っています。したがって、単に行単位で区切っても、すべての行が適切に解析されるわけではありません。一例として、

は、第五のエントリのために、私は私の出力は、ここで 07/01/2016, 6:14 pm - abcde fghe

になりたいです私の現在のコード:

with open('file.txt', 'r') as text_file: 
data = [] 
for line in text_file: 
    row = line.strip() 
    data.append(row) 
+0

は万が一自身が二重引用符に含まれる改行を含めることができるデータ、ですか? –

+0

'データ'がどのように見えるかを表示できますか?あなたの説明からは不明です。私は収入を見ますが、どのように結果が見えるべきかは明確ではありません。 – TitanFighter

+0

'data'の各要素を日付で始めることを望みます。 – Imran

答えて

1

あなたの例の入力を考えると、あなたは前方先読みでregexを使用することができます。

pat=re.compile(r'^(\d\d\/\d\d\/\d\d\d\d.*?)(?=^^\d\d\/\d\d\/\d\d\d\d|\Z)', re.S | re.M) 

with open (fn) as f: 
    pprint([m.group(1) for m in pat.finditer(f.read())])  

プリント:

['06/01/2016, 10:40 pm - abcde\n', 
'07/01/2016, 12:04 pm - abcde\n', 
'07/01/2016, 12:05 pm - abcde\n', 
'07/01/2016, 12:05 pm - abcde\n', 
'07/01/2016, 6:14 pm - abcde\n\nfghe\n', 
'07/01/2016, 6:20 pm - abcde\n', 
'07/01/2016, 7:58 pm - abcde\n\nfghe\n\nijkl\n', 
'07/01/2016, 7:58 pm - abcde\n'] 

Dropboxの例では、印刷物:

['11/11/2015, 3:16 pm - IK: 12\n', 
'13/11/2015, 12:10 pm - IK: Hi.\n\nBut this is not about me.\n\nA donation, however small, will go a long way.\n\nThank you.\n', 
'13/11/2015, 12:11 pm - IK: Boo\n', 
'15/11/2015, 8:36 pm - IR: Root\n', 
'15/11/2015, 8:36 pm - IR: LaTeX?\n', 
'15/11/2015, 8:43 pm - IK: Ws\n'] 

0123を削除する場合はキャプチャされたものにが含まれていれば、上のリストの理解にm.group(1).strip().replace('\n', '')を追加するだけです。正規表現の


説明:

^(\d\d\/\d\d\/\d\d\d\d.*?)(?=^^\d\d\/\d\d\/\d\d\d\d|\Z) 

^              start of line 
    ^^^^ ^         pattern for a date 
        ^        capture the rest... 
         ^       until (look ahead) 
            ^^^   another date 
               ^ or 
                ^end of string 
+0

これは完璧に感謝します! 're.compile'のコードが何をしているのか説明できますか? – Imran

0

あなたは(reモジュールを使用して)正規表現を使用することができへ

import re 
with open('file.txt', 'r') as text_file: 
    data = [] 
    for line in text_file: 
    row = line.strip() 
    if re.match(r'\d{2}/\d{2}/\d{4}.*'): 
     data.append(row) # date: new record 
    else: 
     data[-1] += '\n' + row # no date: append to last record 

# '\d{2}': two digits 
# '.*': any character, zero or more times 
+0

これまでの他のアプローチと同様に、データに区切り文字シーケンス(この形式の日付)が含まれている場合は中断します。 – handle

1

','がセパレータとしてのみ表示されることを考慮すると、私たちはm AYラインはコンマを有するかどうかを確認し、そうでない場合は最後の行にそれを連結:長さ

data = [] 

with open('file.txt', 'r') as text_file: 
    for line in text_file: 
     row = line.strip() 
     if ',' not in row: 
      data[-1] += '\n' + row 
     else: 
      data.append(row) 
+0

これまでのところ、コンマがデータに現れないようにしています(実際には、質問のコメントにリンクされているデータファイルにはいくつかあります)。確実な分離は不可能です。 – handle

+0

私が掲示したとき、質問には例だけがあり、私のコードは「おそらく働くことができる最も単純なもの」となりました。しかし、あなたが正しいコメントにリンクされたデータでは、それはうまくいかないでしょう... –

0

簡易試験:

#!python3 
#coding=utf-8 

data = """06/01/2016, 10:40 pm - abcde 
07/01/2016, 12:04 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 6:14 pm - abcde 

fghe 
07/01/2016, 6:20 pm - abcde 
07/01/2016, 7:58 pm - abcde 

fghe 

ijkl 
07/01/2016, 7:58 pm - abcde""" 

lines = data.split("\n") 
out = [] 
for l in lines: 
    c = l.strip() 
    if c: 
     if len(c) < 10: 
      out[-1] += c 
     else: 
      out.append(c) 
    #skip empty 

for o in out: 
    print(o) 

結果に:

06/01/2016, 10:40 pm - abcde 
07/01/2016, 12:04 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 6:14 pm - abcdefghe 
07/01/2016, 6:20 pm - abcde 
07/01/2016, 7:58 pm - abcdefgheijkl 
07/01/2016, 7:58 pm - abcde 

データに改行が含まれていません!


しかし、この1つのライナーの正規表現は、少なくともサンプルデータのために、それ(数字が続く改行で分割)を行う必要があります(改行データは、数字が続く改行含まれている場合):

#!python3 
#coding=utf-8 

text_file = """06/01/2016, 10:40 pm - abcde 
07/01/2016, 12:04 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 6:14 pm - abcde 

fghe 
07/01/2016, 6:20 pm - abcde 
07/01/2016, 7:58 pm - abcde 

fghe 

ijkl 
07/01/2016, 7:58 pm - abcde""" 

import re 
data = re.split("\n(?=\d)", text_file) 

print(data) 

for d in data: 
    print(d) 

を出力:(先読みで固定)

['06/01/2016, 10:40 pm - abcde', '07/01/2016, 12:04 pm - abcde', '07/01/2016, 12:05 pm - abcde', '07/01/2016, 12:05 pm - abcde', '07/01/2016, 6:14 pm - abcde\n\ 
nfghe', '07/01/2016, 6:20 pm - abcde', '07/01/2016, 7:58 pm - abcde\n\nfghe\n\nijkl', '07/01/2016, 7:58 pm - abcde'] 
06/01/2016, 10:40 pm - abcde 
07/01/2016, 12:04 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 12:05 pm - abcde 
07/01/2016, 6:14 pm - abcde 

fghe 
07/01/2016, 6:20 pm - abcde 
07/01/2016, 7:58 pm - abcde 

fghe 

ijkl 
07/01/2016, 7:58 pm - abcde 

+0

データに改行+数字が含まれていると失敗し、正規表現を拡張する必要があります。一方、データにデータヘッダのような新しい行が含まれていると、このメソッドは[データを墨塗りすることなく、デリミタなしで]簡単に壊れます。 – handle

+0

日付のいずれかが '12/21/2016 '? 're.split(r '\ n \ d'、txt)'を使用すると、日付は '2/21/2016'になります... – dawg

+0

桁が消えていることに気付かなかった。 – handle

関連する問題