假设我有一个电影类型的文本文件,其中包含每种类型下我最喜欢的电影。
【类别】恐怖:
- 电影
- 电影
- 电影
【类别】喜剧:
- 电影
【类别】作用:
- 电影
- 电影
我将如何创建一个函数,将某个 [category] 以下的所有电影标题提取并打包到一个数组中,而不会溢出到另一个类别中?
假设我有一个电影类型的文本文件,其中包含每种类型下我最喜欢的电影。
【类别】恐怖:
- 电影
- 电影
- 电影
【类别】喜剧:
- 电影
【类别】作用:
- 电影
- 电影
我将如何创建一个函数,将某个 [category] 以下的所有电影标题提取并打包到一个数组中,而不会溢出到另一个类别中?
您可以通过这种方式逐行解析文件:
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']
已经给出了其他人对您的文本文件格式的建议,我只是提出另一个建议......如果可以重写您的文件,一个简单的解决方案可能是将其更改为 -ConfigParser
可读(和可写)文件:
[恐怖] 1:电影 2:电影 3:电影 [喜剧] 1:电影 [行动] 1:电影 2:电影
使用负前瞻:
\[category\](?:(?!\[category\]).)*
将匹配一个完整的类别(如果正则表达式是使用该re.DOTALL
选项编译的)。
您可以使用分别获取类别和内容
\[category\]\s*([^\r\n]*)\r?\n((?:(?!\[category\]).)*)
匹配后,mymatch.group(1)
将包含类别, mymatch.group(2)
并将包含电影标题。
Python 3.1 中的示例(使用您的字符串 as 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
键下的字典中。