拆分文本文件中的内容

时间:2017-06-27 08:11:38

标签: python

我有一个包含以下内容的文本文件:

Number1 (E, P) (F, H)
Number2 (A, B) (C, D)
Number3 (I, J) (O, Z) 

我或多或少知道如何阅读它以及如何将它的值输入我的程序,但我想知道如何正确地分成“数字1”,“(E,P)”和“(F , H)”。后来,如果“Number1”包含“(E,P)”,我希望能够检查我的程序。

def read_srg(name):
    filename = name + '.txt'
    fp = open(filename)
    lines = fp.readlines()

    R = {}
    for line in lines:
        ??? = line.split()

    fp.close()

    return R

3 个答案:

答案 0 :(得分:6)

我认为最简单/最可靠的方法是使用正则表达式:

import re
regex = re.compile(r"([^()]*) (\([^()]*\)) (\([^()]*\))")
with open("myfile.txt") as text:
   for line in text:
       contents = regex.match(line)
       if contents:
           label, g1, g2 = contents.groups()
           # now do something with these values, e. g. add them to a list

<强>解释

([^()]*)      # Match any number of characters besides parentheses --> group 1
[ ]           # Match a space
(\([^()]*\))  # Match (, then any non-parenthesis characters, then ) --> group 2
[ ]           # Match a space
(\([^()]*\))  # Match (, then any non-parenthesis characters, then ) --> group 3

答案 1 :(得分:1)

由于括号内有空格,最好使用regular expression,而不仅仅是分割线。

这是您的read_srg功能,其中集成了正则表达式检查:

import re

def read_srg(name):
    with open('%s.txt' % (name, ), 'r') as text:
        matchstring = r'(Number[0-9]+) (\([A-Z,\s]+\)) (\([A-Z,\s]+\))'
        R = {}
        for i, line in enumerate(text):
            match = re.match(matchstring, line)
            if not match:
                print 'skipping exception found in line %d: %s' % (i + 1, line)
                continue
            key, v1, v2 = match.groups()
            R[key] = v1, v2
        return R

from pprint import pformat
print pformat(read_srg('example'))

要阅读字典并对键和值执行检查,您可以稍后执行以下操作:

test_dict = read_srg('example')
for key, (v1, v2) in test_dict.iteritems():
    matchstring = ''
    if 'Number1' in key and '(E, P)' in v1:
        matchstring = 'match found: '
    print '%s%s > %s %s' % (matchstring, key, v1, v2)

这种方法的一大优点是,您还可以使用正则表达式来检查您的文件是否因某种原因而格式不正确。 这就是匹配规则非常严格的原因:

matchstring = r'(Number[0-9]+) (\([A-Z,\s]+\)) (\([A-Z,\s]+\))'

  • (Number[0-9]+)仅匹配由Number后跟任意位数
  • 组成的单词
  • (\([A-Z,\s]+\))只会匹配()中包含大写字母或,或空格的字符串

我在你的评论中读到文件的格式总是一样的,所以我假设它是程序生成的。 仍然,您可能想要检查其完整性(或者确保您的代码在某些时候生成txt文件的过程更改其格式时不会中断)。 根据您的理智检查要求的严格程度,您可以进一步推动以上内容:

  • 如果您知道Number后不应超过3位数,则可以将(Number[0-9]+)更改为(Number[0-9]{1,3})(将匹配限制为1,2或3位数)
  • 如果您想确定括号中的格式始终是由", "分割的两个单个大写字母,则可以将(\([A-Z,\s]+\))更改为(\([A-Z], [A-Z]\))

答案 2 :(得分:0)

你真的很亲密。试试这个:

def read_srg(name):    
    with open(name + '.txt', 'r') as f:
        R = {}
        for line in f:
            line = line.replace(', ', ',')  # Number1 (E, P) (F, H) -> Number1 (E,P) (F,H)
            header, *contents = line.strip().split()  # `header` gets the first item of the list and all the rest go to `contents`
            R[header] = contents
    return R

检查会员资格可以稍后进行:

if "(E,P)" in R["Number1"]:
    # do stuff

我没有测试过,但应该没问题。如果有任何问题,请告诉我。