如何使用唯一分隔符解析文本文件?

How to parse text file using unique delimiters?

Python Spyder 上的 3.5.2 2.x

我有数千个文本文件,它们采用以下半结构化格式。

下面是一个文件one.txt:

Goodsign:       Klisti upto 15:57         Bad Omen:     Gated zone      
 
 
Dusk Attack:        Uptime      Dusk Rest:      Winters

下面是第二个文件second.txt

Goodsign:       Kukul upto 12:60          Bad Omen:     Open zone       
 
 
Dusk Attack:        Downtime        Dusk Rest:      Summers Daring Tribe: Mojars of Moana

现在我想解析这两个文件并获取标签 Goodsign 的值:在 one.txt 中为 "Klisti upto 15:57",在第二种情况中为 "Kukul upto 12:60"。

对于下一组变量再次使用相同的 Bad Omen:获取值 "Gated zone" 和第二种情况 Bad Omen:"Open zone".

对于下一组变量,再次忽略   并获取标签 "Dusk Attack:" 的值,对标签 "Dusk Rest:"

重复相同的操作

除了 : 定界符之外的问题在值之间似乎有一个制表符定界符,例如 Downtime Dusk Rest 之间:有一个间隙“”是这个制表符还是如何解析这种文本?

我尝试实现下面的代码,但是如何仅使用定界符 "Dusk Rest:" 例如,但它给出了之后的所有值。我只需要值 "Downtime" 而它给了我 "Downtime Dusk Rest: Summers Daring Tribe: Mojars of Moana" :

f = open('one.txt', 'r')
lines = f.readlines()
f.close()
searchtxt="Dusk Rest:"
for i, line in enumerate(lines):    
    if searchtxt in line and i+1 < len(lines):
    #print(lines[i+1])
    print(line)
    break

非常感谢您宝贵的回答!

我不知道您的问题是否理解正确...但我认为您正在搜索制表符的转义序列 \t。我想你知道如何使用它。

假设您的字符串由两个示例组成:

>>> txt="""\
... Goodsign:       Klisti upto 15:57         Bad Omen:     Gated zone      
... &nbsp;
... &nbsp;
... Dusk Attack:        Uptime      Dusk Rest:      Winters
... Goodsign:       Kukul upto 12:60          Bad Omen:     Open zone       
... &nbsp;
... &nbsp;
... Dusk Attack:        Downtime        Dusk Rest:      Summers
... """

您可以使用正则表达式获取以下特定字段的值:

>>> import re
>>> pat1=r'^Goodsign:[ \t]*(.*?)[ \t]*(?=Bad Omen:)'
>>> pat2=r'Bad Omen:[ \t]*(.*?)[ \t]*\n'
>>> re.findall(pat1, txt, re.M)
['Klisti upto 15:57', 'Kukul upto 12:60']
>>> re.findall(pat2, txt)
['Gated zone', 'Open zone']

以此类推

如果字段 \t 分隔(您的示例不是),您的正则表达式将变得非常容易编写。


根据评论编辑

Python 3 是强类型的。您的错误是基于 items 被用作字符串的任何内容。

如果您执行以下操作,它应该会起作用:

for fn in [something that generates a list of file names...]
    with open(fn) as f:
        txt=f.read()
        m=re.search(pat1, txt, re.M)
        if m:
            print(m.group(1))

处理这些文件的另一种方法是在正则表达式上拆分它们,可能像这样。

有用的信息似乎被至少两个连续的空格分隔开。我们可以分开这些。同时我们可以安排消除前导的无退格 HTML 元素,如果我们可以假设它们总是 &nbsp;\s 的形式。否则,他们将不得不被分开对待。拆分字段后,我们可以使用 list 类型的 index 方法来查找拆分项中的字段名称以形成值。 (这允许我们在某处不恰当地拆分文件内容的可能性;我们可以将一个字段重新粘合在一起。

import re

for file_name in ['one.txt', 'second.txt']:
    print (file_name)
    with open(file_name) as f:
        content = f.read()
        items = re.split(r'\s{2,}(?:&nbsp;\s)*', content)
        print (items)
        results = {}
        results['Goodsign:'] = ' '.join(items[1: items.index('Bad Omen:')])
        results['Bad Omen:'] = ' '.join(items[1+items.index('Bad Omen:'): items.index('Dusk Attack:')])
        results['Dusk Rest:'] = ' '.join(items[1+items.index('Dusk Attack:'):])
        results['Dusk Attack:'] = ' '.join(items[1+items.index('Dusk Attack:'): items.index('Dusk Rest:')])
        results['Dusk Rest:'] = ' '.join(items[1+items.index('Dusk Rest:'):])
        for result in results:
            print (result, results[result])

这是输出:

one.txt
['Goodsign:', 'Klisti upto 15:57', 'Bad Omen:', 'Gated zone', 'Dusk Attack:', 'Uptime', 'Dusk Rest:', 'Winters']
Bad Omen: Gated zone
Goodsign: Klisti upto 15:57
Dusk Attack: Uptime
Dusk Rest: Winters
second.txt
['Goodsign:', 'Kukul upto 12:60', 'Bad Omen:', 'Open zone', 'Dusk Attack:', 'Downtime', 'Dusk Rest:', 'Summers']
Bad Omen: Open zone
Goodsign: Kukul upto 12:60
Dusk Attack: Downtime
Dusk Rest: Summers