python如何检查打开和关闭标签

时间:2016-03-03 00:52:14

标签: python xml xml-parsing tags

我有类似XML的文件,但它不是XML或HTML。

文件示例:

<config-file>
   name myconfig
   date 3-2-2016
</config-file>
  <client>
   <"ABC - CDE & 123">
   </"ABC - CDE & 123">
  </client>

我们经常编辑此文件并搞乱打开或关闭。不要关闭甚至错过地点&#39;&lt;&#39;或者&#39;&gt;&#39;。 试图找到一种解析文件的好方法,以确保它已打开和关闭。 我在考虑:

通过每一行循环,并记录它是否以 < + any characters >并确保结束 </ + any characters>如果没有,则会引发模式错误。

欢迎任何帮助。

1 个答案:

答案 0 :(得分:1)

你有基础知识。你只关心三种情况:

  1. 开始标记
  2. 结束标记
  3. 其他一切(忽略)
  4. 使用正则表达式查找开头和&amp;结束标签;确保开始表达式排除斜杠作为第二个字符。现在,制作一个简单的堆栈:一个字符串列表就可以了。此列表将保留打开的标签。

    操作:

    • 开始标记:提取标记(剥离尖括号)。将它推到列表的前面。
    • 结束标记:提取标记(剥离尖括号和前导斜杠)。检查此标记是否与列表的前面相同。如果是这样,请弹出它。如果没有,请发出错误消息。如果列表中没有任何内容,则有人试图在没有打开时关闭标签;发出消息。
    • EOF:当您的输入用完时,请检查列表。任何剩余的字符串都是未闭合的标签。发出消息。

    请注意,这也允许您进行一些恢复。您可以扫描列表以查看无效的关闭标记是否与堆栈中的更远位置匹配。这表示重叠块。你可以寻找一个紧密的比赛,暗示拼写错误。如果您无法打开,则可以发出消息并忽略它。这些步骤使您有机会发现多个错误。

    哦,到底是什么......我已经做了足够多次......

    stack = []
    
    with open("parse_test_1.txt", 'r') as parse_file:
        for line in parse_file:
            print "INPUT LINE:", line
            ltag = line.find('<')
            if ltag > -1:
                rtag = line.find('>')
                if rtag > -1:
                    # Found left and right brackets: grab tag
                    tag = line[ltag+1: rtag]
                    open_tag = tag[0] != '/'
                    if open_tag:
                        # Add tag to stack
                        stack.append(tag)
                        print "TRACE open", stack
                    else:
                        tag = tag[1:]
                        if len(stack) == 0:
                            print "No blocks are open; tried to close", tag
                        else:
                            if stack[-1] == tag:
                                # Close the block
                                stack.pop()
                                print "TRACE close", tag, stack
                            else:
                                print "Tried to close", tag, "but most recent open block is", stack[0]
                                if tag in stack:
                                    stack.remove(tag)
                                    print "Prior block closed; continuing"
    
    if len(stack):
        print "Blocks still open at EOF:", stack