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

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

ただいまの
回答率

90.35%

  • Python 3.x

    8412questions

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

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 188

yoshii

score 4

 前提・実現したいこと

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

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となります。
よろしくお願いいたします。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

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

def get_blocks(data):
    blocks = []
    for line in data:
        if line.startswith('\\ref'):
            blocks.append([line])
        else:
            blocks[-1].append(line)
    return blocks

def get_date(block):
    for line in block:
        if line.startswith('\dtrc '):
            return ''.join(line.split()[-1].split())

def generate_insert_new_tag():
    date_counter = {}
    def insert_new_tag(block, date):
        if date in date_counter:
            date_counter[date] += 1
        else:
            date_counter[date] = 1
        text = '\elic.id {0}.{1:0>4}\n'.format(date, date_counter[date])
        return block[:1] + [text] + block[1:]
    return insert_new_tag


fname = 'in-text'

with open(fname, 'r') as f:
    data = f.readlines()

insert_new_tag = generate_insert_new_tag()

blocks = get_blocks(data)
for i, block in enumerate(blocks):
    date = get_date(block)
    blocks[i] = insert_new_tag(block, date)

ans = ''.join([''.join(block) for block in blocks])
print(ans)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/02/20 07:21

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

    キャンセル

+1

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

import re

data = [] # データの一時蓄積用 
n_for_date = dict() # 日付ごとの連番を格納するオブジェクト

with open("testdata.txt", "r") as f:
  line = f.readline()
  while line:
    if line=="\ref":
      すでにdataに蓄積があるなら吐き出す。このときelic.idにn_for_date[date]を追記
    date = re.findall("\dtrc (\d\d\d\d-\d\d-\d\d)", line)
    if len(date)==1:
      n_for_date[date]が存在するならそれに1足す。なければn_for_date[date]=1
    data.append(line)
  最後に残ったdataを吐き出す

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Python 3.x

    8412questions

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