解析字符串模式(Python)

时间:2013-05-27 19:02:01

标签: python string-parsing

我有一个包含以下数据的文件:

<<row>>12|xyz|abc|2.34<</row>>
<<eof>>

该文件可能有多行,如下所示。我正在尝试设计一个解析器,它将解析此文件中存在的每一行并返回包含所有行的数组。这样做的最佳方式是什么?代码必须用python编写。代码不应采用不以<<row>>开头的行或应该引发错误。

=======&GT;更新&lt; ========

我刚发现特定<<row>>可以跨越多行。所以我的代码和下面的代码不再起作用了。有人可以建议一个有效的解决方案吗?

数据文件可以包含数百到数千行。

3 个答案:

答案 0 :(得分:1)

def parseFile(fileName):
  with open(fileName) as f:

    def parseLine(line):
      m = re.match(r'<<row>>(\d+)\|(\w+)\|(\w+)\|([\d\.]+)<</row>>$', line)
      if m:
        return m.groups()

    return [ values for values in (
      parseLine(line)
        for line in f
        if line.startswith('<<row>>')) if values ]

和?我与众不同吗? ; - )

答案 1 :(得分:1)

没有正则表达式的简单方法:

output = []
with open('input.txt', 'r') as f:
    for line in f:
        if line == '<<eof>>':
            break
        elif not line.startswith('<<row>>'):
            continue
        else:
            output.append(line.strip()[7:-8].split('|'))

这会使用以<<row>>开头的每一行,直到一行只包含<<eof>>

答案 2 :(得分:0)

一个好的实践是测试不需要的案例并忽略它们。一旦确定有一条符合要求的生产线,就可以对其进行处理。请注意,实际处理不在if语句中。没有将行分成几行,您只需要两个测试:

rows = list()
with open('newfile.txt') as file:
    for line in file.readlines():
        line = line.strip()
        if not line.startswith('<<row>>'):
            continue
        if not line[-8:] == '<</row>>':
            continue
        row = line[7:-8]
        rows.append(row)

由于行分为几行,因此在某些情况下您需要保存前一行:

rows = list()
prev = None
with open('newfile.txt') as file:
    for line in file.readlines():
        line = line.strip()
        if not line.startswith('<<row>>') and prev is not None:
            line = prev + line
        if not line.startswith('<<row>>'):
            continue
        if not line[-8:] == '<</row>>':
            prev = line
            continue
        row = line[7:-8]
        rows.append(row)
        prev = None

如果需要,您可以使用以下内容拆分列:cols = row.split('|')