我有以下数据,这是gedcom文件(家谱树数据文件)的一部分
0 @I4@ 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 @F3@
0 @I5@ 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)
使用示例代码编辑问题。这是一个解决方案,当在一行中遇到'BIRT'时设置触发器,并且只有在设置时,才输出一行中带有'DATE'的行。请注意,如果您还希望在“BIRT”行之后只需要
代码:
#! /usr/bin/env python
from __future__ import print_function
d = """
0 @I4@ 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 @F3@
0 @I5@ 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
中的文本块中创建一个列表。
如果您已经在列表foo
中有一个行列表,比如因为从文件中读取或其他行,您可以改写:
for line in foo:
从文件中读取时,您经常会在“行”中包含换行字符,因此您经常会在for ...循环标题后看到s_line = line.strip()
短,以摆脱那个以及周围的任何空白区域“想要那条线上的东西”。 HTH
更新:来自OP的好收获。答案中有一个拼写错误,写道:
if token_trigger and token_grep in line:
而不是正确的:
if trigger_found and token_grep in line:
这样,在成功打印想要的BIRTH DATE之后将触发器重置为False
是没用的。
答案 1 :(得分:0)
以下是我一次性出现的东西,它不漂亮而优雅,但你可以用它作为参考来构建你自己的解决方案
def test():
text = ''' 0 @I4@ 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 @F3@
0 @I5@ 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()
然后在解决方案中继续使用相同的代码
答案 2 :(得分:0)
使用grep
:
$ grep -A1 '1 BIRT' so.txt | grep -E '^2'
2 DATE 23 OCT 1930
2 DATE 15 SEP 1928