使用堆栈验证HTML脚本

时间:2017-02-07 20:40:20

标签: python python-3.x stack

我尝试创建一个程序,该程序使用堆栈来检查HTML文件是否具有正确数量的结束标记和结束标记。

我使用的堆栈类非常基本:

class Stack:
    def __init__(self):
        self.items = []

    def isEmpty(self):
        return self.items == []

    def push(self, item):
        self.items.append(item)

    def pop(self):
        return self.items.pop()

    def peek(self):
        return self.items[len(self.items)-1]

    def size(self):
        return len(self.items)

到目前为止,我为HTML检查程序创建的代码是:

def htmlChecker(html):
    htmlStack = Stack()

    htmlOpen = ['<html>','<head>','<title>','<body>',\
                '<p>','<b>','<u>','<div>','<span>']

    htmlClose = ['</html>','</head>','</title>','</body>',\
                 '</p>','</b>','</u>','</div>','</span>']

    htmlList = html.split()

    for opener in htmlList:
        if opener in htmlOpen:
            htmlStack.push(opener)
        for closer in htmlClose:
            if htmlStack.pop() == closer.replace('/',''):
                return True
            else:
                return False

我知道让两个列表中的开启者和关闭者可能效率不高,但我对代码非常基本以了解问题。

如果我插入'<html> <head> </head> <body> </body> </html>'我应该获得True的回复,但是当我输入'<html> <head> </head> <body> </body>'时,我还是应该返回True得到False。 我已经使用for循环和缩进玩了很多,我仍然无法弄清楚为什么它不会因错误的脚本而返回False

2 个答案:

答案 0 :(得分:0)

第一个结束标记后立即终止该功能

for opener in htmlList:
    if opener in htmlOpen:
        htmlStack.push(opener)
    for closer in htmlClose:
        if htmlStack.pop() == closer.replace('/',''):
            return True
        else:
            return False

无论最后if条件是True还是False,您返回以及该程序。您应该return False 。如果情况确实存在,您应该继续前进,直到下一个令牌中的一个失败,或者您到达终点,在这种情况下您应该返回True。所以:

for opener in htmlList:
    if opener in htmlOpen:
        htmlStack.push(opener)
    for closer in htmlClose:
        if htmlStack.isEmpty() or htmlStack.pop() != closer.replace('/',''):
            return False
return True

请注意,您不必编译HTML标记本身,您可以使用正则表达式来简化生活。但这可能值得另一个问题。

答案 1 :(得分:0)

除了早期退出,你可以做一个比嵌套for循环更好的方法,只需检查htmlClose中的入站值,其中包含来自堆栈顶部的pop { :

if len(htmlList) % 2: 
    return False
for v in htmlList:
    if v in htmlOpen:
        htmlStack.push(v)
    else:
        if htmlStack.isEmpty(): 
            return False
        else:
            v2 = htmlStack.pop()
            if v.replace('/', '') != v2:
                return False
return True

如果显示关闭标记时堆栈isEmpty,则没有开放标记(您可以修改代码并立即pop使用try-except抓住特殊情况并返回)。如果从末尾弹出的值与结束标记不匹配,则表示您没有余额。