質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

953閲覧

Pythonの特殊変換とデータ差し込みを実現したいです。

yoshii

総合スコア14

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/02/18 20:35

編集2018/02/18 20:37

前提・実現したいこと

ここに質問の内容を詳しく書いてください。

Pythonについて、以前も同じような質問をさせていただいたのですが、
少し変換前のデータ形式が変わってしまったため、再度ご協力いただけると幸いです。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
【やりたいことについて】
\refから始まる数行(ここでは6行)がひとつのブロック(1データ)となってます。
やりたいことは,\dtrcから始まる行にある日付を拾い、以下のようにしたいです。
(※日付部分は、予め昇順にソートされたデータとなります。)

(例)
\ref
\aaaaaa
\bbbbbb
\cccccc
\dddddd
\dtrc 2017-08-25


\ref
\elic.id 20170825.0001
\aaaaaa
\bbbbbb
\cccccc
\dddddd
\dtrc 2017-08-25

\refから始まる最初の行の次に、\elic.idを挿入し、
そのあとに\dtrcにある日付(ハイフンをとる)、
そのあとにピリオド、そして4桁の連番(0001から開始)。
そして,連番は日付部分が変わったら,また0001から振り直す。

[サンプルデータ(変換前)]

\ref
\aaaaaa
\bbbbbb
\cccccc
\dddddd
\dtrc 2017-08-25 #日付が同じ場合、連番付与(→この場合は、0001)

\ref
\eeeeee
\ffffff
\gggggg
\hhhhhh
\dtrc 2017-08-25 #日付が同じ場合、連番付与(→この場合は、0002)

\ref
\iiiiii
\jjjjjj
\kkkkkk
\llllll
\dtrc 2017-08-26 #日付が異なる場合、0001をセット

↓↓↓

[サンプルデータ(変換後)] 

\ref
\elic.id 20170825.0001
\aaaaaa
\bbbbbb
\cccccc
\dddddd
\dtrc 2017-08-25

\ref
\elic.id 20170825.0002
\eeeeee
\ffffff
\gggggg
\hhhhhh
\dtrc 2017-08-25

\ref
\elic.id 20170826.0001
\iiiiii
\jjjjjj
\kkkkkk
\llllll
\dtrc 2017-08-26

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

発生している問題・エラーメッセージ

該当のソースコード

試したこと

アルゴリズム上もそうですが、Python初心者のため、どのように表現したらよいか分からず、
まだ試せておりません。。

頭で考えているイメージ
(より効率のよい方法があるかもしれませんが、、)

①元データからあらかじめ、\dtrcから始まる行を取得し、\elic.idから始まるデータ準備をする。
(このタイミングでデータ変換も可能か?
取得できたレコード数は、②で使えそうか?)

②元データをfor文で回し、\refの次の行に、
\elic.idから始まるデータを順次差し込むことは可能か?

補足情報(FW/ツールのバージョンなど)

実行環境は、Python3となります。
よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

だいたいばらしてみました。

python

1def get_blocks(data): 2 blocks = [] 3 for line in data: 4 if line.startswith('\ref'): 5 blocks.append([line]) 6 else: 7 blocks[-1].append(line) 8 return blocks 9 10def get_date(block): 11 for line in block: 12 if line.startswith('\dtrc '): 13 return ''.join(line.split()[-1].split()) 14 15def generate_insert_new_tag(): 16 date_counter = {} 17 def insert_new_tag(block, date): 18 if date in date_counter: 19 date_counter[date] += 1 20 else: 21 date_counter[date] = 1 22 text = '\elic.id {0}.{1:0>4}\n'.format(date, date_counter[date]) 23 return block[:1] + [text] + block[1:] 24 return insert_new_tag 25 26 27fname = 'in-text' 28 29with open(fname, 'r') as f: 30 data = f.readlines() 31 32insert_new_tag = generate_insert_new_tag() 33 34blocks = get_blocks(data) 35for i, block in enumerate(blocks): 36 date = get_date(block) 37 blocks[i] = insert_new_tag(block, date) 38 39ans = ''.join([''.join(block) for block in blocks]) 40print(ans)

投稿2018/02/19 05:53

mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoshii

2018/02/19 22:21

丁寧に回答いただき、ありがとうございます。 回答いただいたソースコード、ほぼそのままでうまく動きました。 非常に助かりました。本当にありがとうございました。
guest

0

ざっくりこんな感じじゃないかな。

python

1import re 2 3data = [] # データの一時蓄積用 4n_for_date = dict() # 日付ごとの連番を格納するオブジェクト 5 6with open("testdata.txt", "r") as f: 7 line = f.readline() 8 while line: 9 if line=="\ref": 10 すでにdataに蓄積があるなら吐き出す。このときelic.idにn_for_date[date]を追記 11 date = re.findall("\dtrc (\d\d\d\d-\d\d-\d\d)", line) 12 if len(date)==1: 13 n_for_date[date]が存在するならそれに1足す。なければn_for_date[date]=1 14 data.append(line) 15 最後に残ったdataを吐き出す

投稿2018/02/18 21:17

KojiDoi

総合スコア13671

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問