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

时间:2017-05-26 16:06:37

标签: python python-3.x parsing text-files delimiter

Spyder 2.x上的Python 3.5.2

我有数以千计的文本文件,这些文件采用以下格式的半结构化文件。

下面是一个文件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”。

对于下一组变量,再次忽略& nbsp并获取标签“Dusk Attack:”的值,重复相同的标签“Dusk Rest:”

除了:分隔符之外的问题似乎在值之间存在制表符分隔符,例如在停机时间黄昏休息之间:有一个间隙“”是这个选项卡还是如何解析这种文本?

我尝试实现下面的代码,但是如何仅使用分隔符“Dusk Rest:”,但它之后给出了所有值。我只需要重视“停机时间”而它给我“停机黄昏休息:萨默斯大胆的部落:莫阿纳的莫哈斯”:

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

非常感谢您的宝贵答案!

3 个答案:

答案 0 :(得分:1)

假设您的字符串包含两个示例:

>>> 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))

答案 1 :(得分:1)

使用这些文件的另一种方法是将它们拆分为正则表达式,也许就像这样。

有用的信息位似乎被至少两个连续的空白项分开。我们可以分开那些。同时,如果我们可以假设它们总是采用&nbsp;\s形式,我们可以安排消除前导的无后退HTML元素。否则他们将不得不单独对待。拆分字段后,我们可以使用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

答案 2 :(得分:0)

我不知道是否理解你的问题是正确的...但我认为你为了标签而进行了转发序列的搜索。我想你知道如何使用它。