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

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

ただいまの
回答率

90.34%

  • Python 2.7

    1335questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

ファイルの中から特定の文字列の抽出

解決済

回答 2

投稿

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

tasss

score 4

ダンプデータの中から、”abcd"という文字を発見したら、”xyz”という文字を見つけるまで、そこの間の文字を抽出し、ファイルに出力したいのですが、どのようなソースコードを書けばよいか教えてください。

ダンプデータの中には、抽出したい文字の集合は複数あります。
つまり、
abcd(......
......   ←この括弧の中をファイルに出力したい(実際に括弧はないです)
......)xyz
.....
.....
.....
abcd(...
.....
.....
.....)xyz
.....
という感じです。(わかりずらくてすみません)

ファイルの読み込みは一行ずつ読み込むようにしたいです。

よろしくお願いします

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

0

行毎に処理する例です。
意外と手強いですね。

class Unwrap(object):
    '''
    複数行にまたがる囲み「<-~->」を取り除く
    '''
    def __init__(self, stMark="<-", edMark="->"):

        self.__stMark = stMark      # 開始、終了記号
        self.__edMark = edMark
        self.__stLen = len(stMark)
        self.__edLen = len(edMark)

        self.__curLv = 0   # 現在の囲みレベル
        self.__strBuf = "" # 囲み内の文字列保持用バッファ

        self.__initLine("")

    def __initLine( self,str):
        '''
        1行文字列をセット
        '''

        self.__lineStr = str        # 走査対象の文字列
        self.__lenLine = len(str)

        self.__state = ""   # 行の走査状態 「囲み開始」など
        self.__curPos = 0   # 走査文字位置
        self.__markPos = -1 # 開始or終了記号の文字位置

        self.__bufPos = 0   # バッファへの文字列取得位置

    def __moveNext(self):
        '''
        文字列を次の位置まで走査
        '''

        # 開始、終了記号を探す
        stPos = self.__lineStr.find( self.__stMark, self.__curPos)
        edPos = self.__lineStr.find( self.__edMark, self.__curPos)

        self.__state = "end"    # 行末
        self.__curPos = -1
        self.__markPos = -1

        lenMark = -1
        if stPos >= 0 and edPos >= 0:

            if stPos < edPos:
                self.__state = "st" # 囲み開始
            else:
                self.__state = "ed" # 囲み終了

        elif stPos >= 0:
            self.__state = "st"
        elif edPos >= 0:
            self.__state = "ed"

        if self.__state == "st":
            self.__markPos = stPos
            lenMark = self.__stLen
        elif self.__state == "ed":
            self.__markPos = edPos
            lenMark = self.__edLen

        self.__curPos = self.__markPos + lenMark
        if self.__curPos >= self.__lenLine:
            self.__curPos = -1

    def unwrapLine(self, lineStr):
        '''
        1行分の結果を返す
        '''

        self.__initLine( lineStr)
        aRet = []
        while True:
            self.__moveNext()

            if self.__curLv == 0:      # 囲みなし

                if self.__state == "st":
                    self.__curLv += 1
                    self.__bufPos = self.__curPos

            else:               # 囲み中

                if self.__state == "ed":

                    self.__curLv -= 1

                    if self.__curLv == 0:  # 囲み完全に終了

                        if self.__bufPos >= 0:  # 取得残を取り込む
                            self.__strBuf += self.__lineStr[self.__bufPos:self.__markPos]

                        aRet.append(self.__strBuf)

                        self.__bufPos = 0
                        self.__strBuf = ""

                elif self.__state == "st": # 囲み開始
                    self.__curLv += 1

            if self.__state == "end":   # 「行末」
                if self.__curLv > 0 and self.__bufPos >= 0:  # 取得残を取り込む
                    self.__strBuf += self.__lineStr[self.__bufPos:]
                break

        return aRet

def unwrap( aLine):
    ul = Unwrap()
    aRet = []
    for line in aLine:
        aOne = ul.unwrapLine( line)
        aRet += aOne
    return aRet

print( unwrap(["<-abc-><-de","f-><-g<-h->->"]))

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/02/02 04:21

    回答ありがとうございます。
    説明も添えていただき、とてもわかりやすかったです。
    ほんとに初歩的な質問だと思いますが、ファイルの読み込みの手順もご説明していただけないでしょうか。
    zipファイルを解凍して、そのファイルの中身を抽出したいです。
    付け足しになってしまい、申し訳ありません。

    キャンセル

  • 2017/02/02 10:14

    ファイル読込、zip解凍ともに検索すれば多くのサンプルが見つかります。
    まずはやってみて、分からない場合は新たに質問してはいかがでしょうか。

    キャンセル

0

Pythonであれば、正規表現を用いるのが一番かと思われます。

import re

# abcdeとxyzの間を取得する。
text = "abcde00000000000000000000xyz"

# A-Za-z0-9の文字を抽出(記号等は含まれない)
result = re.search(r'abcde(?P<data>[A-Za-z0-9].*)xyz', text)

# 条件にマッチしたデータの表示
print result.group('data')

こんな感じでしょうかね。一度試して見てください。正規表現の方法はいくつかあるので、自分のものに合わせて書き換えて見てくださいね

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

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

  • Python 2.7

    1335questions

    Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。