2016-06-15 57 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