映画のジャンルのテキスト ファイルがあり、各ジャンルのお気に入りの映画が含まれているとします。
【カテゴリ】ホラー:
- 映画
- 映画
- 映画
【カテゴリ】コメディ:
- 映画
[カテゴリ] アクション:
- 映画
- 映画
特定の [カテゴリ] * の下にあるすべての映画のタイトルを抽出してパッケージ化し、別のカテゴリに影響を与えずに配列にパッケージ化する関数を作成するにはどうすればよいでしょうか?
映画のジャンルのテキスト ファイルがあり、各ジャンルのお気に入りの映画が含まれているとします。
【カテゴリ】ホラー:
- 映画
- 映画
- 映画
【カテゴリ】コメディ:
- 映画
[カテゴリ] アクション:
- 映画
- 映画
特定の [カテゴリ] * の下にあるすべての映画のタイトルを抽出してパッケージ化し、別のカテゴリに影響を与えずに配列にパッケージ化する関数を作成するにはどうすればよいでしょうか?
あなたのテキストファイル形式についてすでに他の人からアドバイスを受けているので、私は別の提案をしています...ファイルを書き換えることができる場合、簡単な解決策は、それをConfigParser
読み取り可能な(および書き込み可能な)ファイルに変更することです。
[ホラー] 1: 映画 2: 映画 3: 映画 【コメディ】 1: 映画 [アクション] 1: 映画 2: 映画
次のように、ファイルを 1 行ずつ解析できます。
import collections
result=collections.defaultdict(list)
with open('data') as f:
genre='unknown'
for line in f:
line=line.strip()
if line.startswith('[category]'):
genre=line.replace('[category]','',1)
elif line:
result[genre].append(line)
for key in result:
print('{k} {m}'.format(k=key,m=list(result[key])))
収量
Action: ['1. Movie', '2. Movie']
Comedy: ['1. Movie']
Horror: ['1. Movie', '2. Movie', '3. Movie']
否定先読みを使用します:
\[category\](?:(?!\[category\]).)*
1 つのカテゴリ全体に一致します (正規表現がre.DOTALL
オプションを使用してコンパイルされている場合)。
を使用して、カテゴリとコンテンツを別々に取得できます
\[category\]\s*([^\r\n]*)\r?\n((?:(?!\[category\]).)*)
試合後、mymatch.group(1)
カテゴリ mymatch.group(2)
が含まれ、映画のタイトルが含まれます。
Python 3.1 の例 (文字列を として使用mymovies
):
>>> import re
>>> myregex = re.compile(r"\[category\]\s*([^\r\n]*)\r?\n((?:(?!\[category\]).)*)", re.DOTALL)
>>> for mymatch in myregex.finditer(mymovies):
... print("Category: {}".format(mymatch.group(1)))
... for movie in mymatch.group(2).split("\n"):
... if movie.strip():
... print("contains: {}".format(movie.strip()))
...
Category: Horror:
contains: 1. Movie
contains: 2. Movie
contains: 3. Movie
Category: Comedy:
contains: 1. Movie
Category: Action:
contains: 1. Movie
contains: 2. Movie
>>>
import re
re_cat = re.compile("\[category\] (.*):")
categories = {}
category = None
for line in open("movies.txt", "r").read().split("\n"):
line = line.strip()
if not line:
continue
if re_cat.match(line):
category = re_cat.sub("\\1", line)
if not category in categories:
categories[category] = []
continue
categories[category].append(line)
print categories
次の辞書を作成します。
{
'Action': ['Movie', 'Movie'],
'Horror': ['Movie', 'Movie', 'Movie'],
'Comedy': ['Movie']
}
カテゴリ名の一致と削除には同じ正規表現を使用するため、 でコンパイルすると効率的re.compile
です。
category
新しいカテゴリが解析されるたびに変化する実行変数があります。新しいカテゴリを定義していない行はcategories
、適切なキーの下でディクショナリに追加されます。初めて定義されたカテゴリは、正しい辞書キーの下にリストを作成しますが、カテゴリを複数回リストすることもでき、すべてが正しいキーの下に配置されます。
カテゴリが定義される前にリストされた映画は、None
キーの下のディクショナリに含まれます。