提取类别下方的行,并在达到其他类别时停止

时间:2010-11-10 13:41:34

标签: python text-extraction

假设我有一个电影类型的文本文件,每个类型下都有我最喜欢的电影。

  

[类别]恐怖:

     
      
  1. 电影
  2.   
  3. 电影
  4.   
  5. 电影
  6.         

    [类别]喜剧:

         
        
    1. 电影
    2.         

      [类别]行动:

           
          
      1. 电影
      2.   
      3. 电影
      4.   

如何创建一个功能,将某个[类别] *以下的所有电影标题提取并打包成一个数组,而不会溢出到另一个类别中?

4 个答案:

答案 0 :(得分:2)

您可以通过这种方式逐行解析文件:

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']

答案 1 :(得分:2)

已经给出了其他人对你的文本文件格式的建议,我只是踩着给出另一个建议......如果可以重写你的文件,一个简单的解决办法就是把它改成ConfigParser - 可读(文件:

[Horror]
1: Movie
2: Movie
3: Movie

[Comedy]
1: Movie

[Action]
1: Movie
2: Movie

答案 2 :(得分:1)

使用negative lookahead

\[category\](?:(?!\[category\]).)*

将匹配整个类别(如果使用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
>>>

答案 3 :(得分:0)

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键下的字典中。