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

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

ただいまの
回答率

89.05%

python3で特定の範囲の文字を抽出したい

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 6,902

TakamasaIijima

score 15

 前提・実現したいこと

python3とsphinxをつかってドキュメントを作っております。
以下のようなrstテキストにおいて特定の範囲を繰り返し抽出したいのですがうまく行く条件がわかりません。ご教授くださると幸いです。
将来的には抽出後の各配列から"タイトル名の同名.rst"に書き出すプログラムを書きたいです

 rstの中身

=============
sphinxタイトル
=============

サブタイトルA      #ここから
=============
#なんとかかんとか
#文字列
.. code-block:: python
    :lineos:

    python code

#ここまで抽出したい

サブタイトルB
===========
~~~~~~~
~~~~~

サブタイトルC
===========

 期待する出力

サブタイトルA      #ここから
=============
#なんとかかんとか
#文字列
.. code-block:: python
    :lineos:

    python code

   #ここまで抽出したい

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

言語:python3

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 3

+1

test.txtを対象として、「サブタイトル」を含む行から「#ここまで抽出したい」を含む行までを出力するスクリプトを書いてみました。

追記。変数outfileに書き込み先ファイルを持たせるようにし、併せて出力が必要か否かのフラグの機能も持たせるようにしました。
流れとしては間違っていないと思いますが、細かいミスが残っているかもしれません。

import re
outfile = ""

with open("test.txt", "r") as lines:
  for line in lines:
    line=line.rstrip('\r\n')
    if outfile=="":
      m = re.search("サブタイトル([A-Z]+)",line)
      if m:
        outfile = "out_{}.txt".format(m.group(1))
        fo = open(outfile, "w")
        fo.write(line)
        fo.write("\n")
    else:
      fo.write(line)
      fo.write("\n")
      m = re.match("#ここまで抽出したい",line)
      if m:
        fo.close()
        outfile=""

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/02/04 20:31

    KojiDoiさん 
    回答ありがとうございます。
    参考にさせていただきます。
    想定していました動作としましては、AからBまでだけではなくBからCまでもといったように一つのセクションづつをすべて取り出したいのですが,正規表現で=と文字列をうまく使って抽出できたりしますでしょうか..?

    キャンセル

+1

file_names = ['in-rst']

def extracts(data):
    lnums = [i for i,l in enumerate(data) if l.startswith('======')]
    title = data[0:lnums[1]+1]
    results = []
    for i in range(2, len(lnums)-1):
        results.append(''.join(data[lnums[i]-1:lnums[i+1]-2]))
    results.append(''.join(data[lnums[-1]-1:]))
    return title, results

for file_name in file_names:
    with open(file_name, 'r') as f:
        data = f.readlines()
    title, results = extracts(data)
    print(title)
    for item in results:
        print('-'*50 + 'start')
        print(item)
        print('-'*50 + 'end')

in-rstの中身

=============
sphinxタイトル
=============

サブタイトルA      #ここから
=============
#なんとかかんとか
#文字列
.. code-block:: python
    :lineos:

    python code

#ここまで抽出したい

サブタイトルB
===========
~~~~~~~
~~~~~

サブタイトルC
===========

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

check解決した方法

0

頂いた回答を元に元のrstを少しだけ改変して抽出することができました

=============
sphinxタイトル
=============

§サブタイトルA      #ここから->regex replace(Atom側で)で条件を(.+\W)(\n)(\W[==].*)として置換
=============   #置換先文字列を§$1$2$3としてタイトルの頭に§というマーカーを設置
#なんとかかんとか
#文字列
.. code-block:: python
    :lineos:

    python code

#ここまで抽出したい->ここを.*\n.*\n\nで発見させて#---というマーカーを設置

#---


§サブタイトルB
===========
~~~~~~~
~~~~~

#---

§サブタイトルC
===========
...~

以下に抽出用プログラムのコードを記します

import re
import os.path

base = os.path.dirname(os.path.abspath(__file__))
name = os.path.normpath(os.path.join(base, '../対象rstの名前.rst'))

outfile = ""

i = 0

with open(name, "r", encoding="utf-8") as lines:
    for line in lines:
        line = line.rstrip('\n')
        if outfile == "":
            m = re.search("§", line)
            if m:
                i += 1
                outfile = os.path.normpath(os.path.join(base, './result/'+str(i) + line + ".rst"))
                print('sub/3/' +str(i) + line)
                fo = open(outfile, "w", encoding="utf-8")
                fo.write('sub/2/'+line)
                fo.write("\n")
        else:
            fo.write(line)
            fo.write("\n")
            m = re.match("#-.*", line)
            if m:
                fo.close()
                outfile = ""

コードについてアドバイスなどありましたらぜひご教授ください
回答ありがとうございました!
(WindowsのPycharmでopenがUTF-8じゃないのなんとかなんないですかね...Cpとかになっちゃう。。)

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

  • ただいまの回答率 89.05%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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