2016-06-15 111 views
0

我有以下数据是GEDCOM文件(家谱数据文件)遍历列表元素,以获得特定的数据

0 @[email protected] INDI 
1 NAME Milo /Vettle/ 
2 GIVN Milo 
2 SURN Vettle 
2 _MARNM Vettle 
1 SEX M 
1 BIRT 
2 DATE 23 OCT 1930 
1 FAMS @[email protected] 
0 @[email protected] INDI 
1 NAME Rosy /Huleknberg/ 
2 GIVN Rosy 
2 SURN Huleknberg 
2 _MARNM Vettle 
1 SEX F 
1 BIRT 
2 DATE 15 SEP 1928 
1 DEAT Y 
2 DATE 10 MAR 2010 

在上述数据部分第一个数字是一个新的水平数为标签并按照标签论据。我将这些数据保存在列表中。现在,我想搜索'BIRT'标签,当程序击中我想要打印出生日期的下一行时。如果您注意到密切注意'DEAT'标签还有一个日期,但我希望日期后跟'BIRT'标签。

我该如何完成这项任务? 我试图

for line in list: 
    if 'BIRT' in line: 
     if 'DATE' in line: 

      print line 
+0

请[编辑]你的问题,包括你试过什么 –

+0

正如@ cricket_007指出,请编辑您的问题,包括你已经尝试了什么,以何种形式,你有这样的数据?名单?文件? –

+0

是否需要其他编辑? – siddpro

回答

0

感谢编辑与示例代码的问题。这是一个解决方案,当在一行中遇到'BIRT'时设置一个触发器,并且只有在设置时才输出一个'DATE'行。请注意,如果你也只需要在它“日期”线直接继“BIRT”行,你必须修改代码有点;-)

代码:

#! /usr/bin/env python 
from __future__ import print_function 

d = """ 
0 @[email protected] INDI 
1 NAME Milo /Vettle/ 
2 GIVN Milo 
2 SURN Vettle 
2 _MARNM Vettle 
1 SEX M 
1 BIRT 
2 DATE 23 OCT 1930 
1 FAMS @[email protected] 
0 @[email protected] INDI 
1 NAME Rosy /Huleknberg/ 
2 GIVN Rosy 
2 SURN Huleknberg 
2 _MARNM Vettle 
1 SEX F 
1 BIRT 
2 DATE 15 SEP 1928 
1 DEAT Y 
2 DATE 10 MAR 2010 
""" 

trigger_found = False 
token_trigger = 'BIRT' 
token_grep = 'DATE' 

for line in d.split('\n'): 
    if token_trigger in line: 
     trigger_found = True 
     continue 
    if trigger_found and token_grep in line: 
     print(line) 
     trigger_found = False 

测试使用Python v2.7.11运行:

2 DATE 23 OCT 1930 
2 DATE 15 SEP 1928 

与python v3相同。

注:这也可能是更强大的(考虑您的输入作为olny样品),触发像BIRT令牌(用空格填充,作为样本中给出的文字看起来像有可能是文本框可能已经“输入”包含“代码”)如下所示:

2 GIVN BIRTE 

这是一个有效的给定名称。这不会改变此示例中的输出,但它会意外设置“触发器”。

更新(应答在评论一个问题):

这条线上面的代码片段:

for line in d.split('\n'): 

d正文块stoerd通过对换行分割创建一个列表。

如果你已经在列表中有foo行的列表,说是因为从文件或以其他方式阅读,你可以代替写:

for line in foo: 

从文件中读取当你经常换行chacter包含在“行”中,因此在for ...循环头文件后经常会看到s_line = line.strip()短,以便摆脱围绕“该行所需内容”的那个空白空间。 HTH

更新:从OP得到良好的结果。有在回答一个错字,这是写:

if token_trigger and token_grep in line: 

而不是正确的:

if trigger_found and token_grep in line: 

这样一来,想要的出生日期成功后打印重置触发False是无用的。

+0

这是什么类型d =“”“.........”“”。我可以在列表中使用相同的吗? – siddpro

+0

啊,当然,对不起。在python中,你有三重引号的字符串,可以让你携带多行文本,而不需要注入'\ n'字符转义的技巧。我经常用它作为技巧来完成展示。我会更新答案。感谢您的反馈。 – Dilettant

+0

我想要通过列表读取并完成任务的解决方案。你的解决方案是阅读与死亡有关的日期(我不想)。我对这门语言很陌生,仍然在学习,因此面临着这样的问题。 – siddpro

0

以下是我在一杆打,那不是漂亮和优雅的,但你可以使用它作为参考的基础上自己的解决方案

def test(): 

    text = ''' 0 @[email protected] INDI 
       1 NAME Milo /Vettle/ 
       2 GIVN Milo 
       2 SURN Vettle 
       2 _MARNM Vettle 
       1 SEX M 
       1 BIRT 
       2 DATE 23 OCT 1930 
       1 FAMS @[email protected] 
       0 @[email protected] INDI 
       1 NAME Rosy /Huleknberg/ 
       2 GIVN Rosy 
       2 SURN Huleknberg 
       2 _MARNM Vettle 
       1 SEX F 
       1 BIRT 
       2 DATE 15 SEP 1928 
       1 DEAT Y 
       2 DATE 10 MAR 2010''' 
    lines = text.split('\n') 

    tokens = [l.split(' ') for l in lines] 

    tags = [token[1] for token in tokens] 
    indices = [i for i, x in enumerate(tags) if x == 'BIRT'] 

    for i in indices: 
     if tags[i+1] == 'DATE': 
      print(lines[i+1]) 

输出:

 2 DATE 23 OCT 1930 
     2 DATE 15 SEP 1928 

PS:线tokens = [l.split(' ') for l in lines]是假设空间是分隔符。如果它不是现实中的情况下,你可以改变它

更新

既然你是从文件中读取数据可以更换

lines = text.spilt('\n') 

file = open('path_to_file') 
lines = file.readlines() 

然后在解决方案中继续使用相同的代码

+0

这是什么类型的文本='''......''' – siddpro

+0

这是您提供的示例数据,我只是将它分配给变量以方便我使用。你可以从文件中读取它。 –

+0

我现在没有输出!我对这种语言很陌生,因此面临这样的问题 – siddpro

0

使用grep

$ grep -A1 '1 BIRT' so.txt | grep -E '^2' 
2 DATE 23 OCT 1930 
2 DATE 15 SEP 1928