匹配 python 中文件开头或结尾的 space 的正则表达式

Regex to match space in the beginning or end of file in python

我在文本文件中有以下数据。

T79534  TARGETID    T79534      
T79534  FORMERID    TTDI01219       
T79534  TARGNAME    P450-dependent ergosterol synthesis (PDE synth)     
T79534  TARGTYPE    Discontinued target     
T79534  DRUGINFO    D0T5NI  Saperconazole   Discontinued in Phase 2
                
T78590  TARGETID    T78590      
T78590  FORMERID    TTDI01580       
T78590  TARGNAME    Polymorphonuclear neutrophil adhesion (PMNA)        
T78590  TARGTYPE    Discontinued target     
T78590  DRUGINFO    D0OB7J  NPC-15669   Discontinued in Phase 1

我想提取 TARGETIDTARGTYPE 字段的值。我正在使用以下几行 python 代码来获取此数据(target_file 是一个包含此数据的变量:<class 'pandas.core.frame.DataFrame'>)。

for index, row in target_file.iterrows():
    if re.match("r^[A-Z]+.*", str(row['field'])):
        if row['field'] == 'TARGETID':
            target_id = row['value']
        elif row['field'] == 'TARGTYPE':
            target_type = row['value']
        else:
            continue
    elif re.match("r^\s+|$\Z", str(row['field'])): #if matches space or end of file, get the data
        print (target_id, target_type, uniprot_id)   

        #empty the variable for new loop
        target_id = ''
        target_type = ''
    else:
        'do nothing'

我假设 elif 条件下的正则表达式 (re.match("r^\s+|$\Z", str(row['field']))) 不起作用。

预期输出为:

T79534 Discontinued target
T78590 Discontinued target

非常感谢这里的任何帮助

如果没有更多我不知道的条件并且每个块总是有一个 TARGETID 和一个 TARGTYPE,那么你可以在 df:

out = df.loc[df['field'].isin(['TARGETID','TARGTYPE']),'value']
print(out)

Output:
0                 T79534
3    Discontinued target
5                 T78590
8    Discontinued target

如有必要,要使其与您想要的输出完全匹配,您可以使用 out:

for i,k in zip(out[0::2], out[1::2]):
    print(i,k)

Output:
T79534 Discontinued target
T78590 Discontinued target

有帮助吗?

更新: 如果你想直接从文本文件中执行而不创建数据帧,你可以这样做:

with open('000_SO_input3.txt', 'r') as f:
    for line in f:
        if len(line.strip())!=0:
            ID, fields, value = [x.strip() for x in line.split(maxsplit=2)]
            if fields=='TARGETID':
                targetid = value
            elif fields=='TARGTYPE':
                targtype = value
        else:
            print(targetid, targtype)
    print(targetid, targtype) 

如果它不是空行,拆分行并检查搜索词的命中,否则(你有一个空行)打印 targetidtargtype 的当前值。请注意,在最后您再次打印相同的语句,因为最后没有空行并且您的结果不会打印两个变量的最后一个当前值。

编辑 你的代码: 我刚刚查看了您尝试过的代码。首先,两个正则表达式中都有错字。对于 r-string,r 需要在 "..." 之外,所以它必须是 r"^[A-Z]+.*"。您实际上只是搜索一个词,因此这个词也可以搜索 r"\w+"。其次你需要知道你在做什么,你不检查一个大的多行字符串,你检查列 field 的每个单元格,没有必要用 [= 包装 row('field') 25=]。与第二个正则表达式模式相同。您逐个单元格检查,因此您不会在 file 结束时捕获,因为 for 循环在最后一个单元格之后停止。并且空行被自动删除(至少当我将数据从文本文件加载到 df 时是这样),所以你也不会点击它。通常 r"^\s+" 会匹配一个空字符串或只有空格的字符串,但是没有空格所以你的 elif 永远不会被执行。如果你只是插入所有的 if elif 和 else 一些打印语句来查看代码是如何执行的,你会看到。

re.findall似乎更简单。
(我省略了 file-reading 部分,因为您似乎对此没有问题,而且在一个文件中编写示例代码更容易。)

import re 
myfile=(
'T79534  TARGETID    T79534      ',
'T79534  FORMERID    TTDI01219       ',
'T79534  TARGNAME    P450-dependent ergosterol synthesis (PDE synth)     ',
'T79534  TARGTYPE    Discontinued target     ',
'T79534  DRUGINFO    D0T5NI  Saperconazole   Discontinued in Phase 2',
'T78590  TARGETID    T78590      ',
'T78590  FORMERID    TTDI01580       ',
'T78590  TARGNAME    Polymorphonuclear neutrophil adhesion (PMNA)        ',
'T78590  TARGTYPE    Discontinued target     ',
'T78590  DRUGINFO    D0OB7J  NPC-15669   Discontinued in Phase 1',)
target_id = ''
target_type = ''
for f in myfile:
  g = re.findall('\w+\s+(\w+)\s+(\w+)',f)
  if g[0][0] == 'TARGETID':
    target_id = g[0][1] 
  if g[0][0] == 'TARGTYPE':
    target_type = g[0][1] 
  if target_id:
    print(target_id)
  if target_type:
    print(target_type)
  target_id = ''
  target_type=''

输出

T79534
Discontinued
T78590
Discontinued