虽然这是课程的项目作业,但我正在努力了解如何完成项目的特定部分。
我需要浏览一个html文件并检查所有开始语句是否与结束语句匹配。此外,它们必须按正确顺序排列,并且必须使用已实施的堆栈进行检查。截至目前,我正在从文件中提取每个标签。困难的部分似乎是我在这里工作的两个例外。中和。我需要删除这些标记,因此程序不会将它们作为开始或结束语句读取。
class Stack(object):
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[-1]
def getTag(file):
EXCEPTIONS = ['br/', 'meta']
s = Stack()
balanced = True
i = 0
isCopying = False
currentTag = ''
isClosing = False
while i < len(file) and balanced:
if symbol == "<":
if i < (len(file) - 1) and file[i + 1] == "/":
i = i + 1
isClosing == True
isCopying == True
if symbol == ">":
if isClosing == True:
top = s.pop()
if not matches(top, symbol):
balanced = False
else:
**strong text**
s.push(currentTag)
currentTag = ''
isCopying == False
if isCopying == True:
currentTag += symbol
代码读入文件并逐字逐句搜索<string>
。如果它存在,则将其推入堆栈。 matches
函数检查结束语句是否等于开始语句。例外列表是我必须检查的那些将搞乱将字符串放置在堆栈上。我正在努力将它们合并到我的代码中。有任何想法吗?在我继续前进到堆栈之前,我应该通过一个过滤系统来查看该语句是有效还是无效。一个基本的if语句就足够了。
答案 0 :(得分:1)
如果我正确地阅读了您的要求,您就会非常尴尬地解决这个问题。你真正想要做的是tokenize你的文件,所以你应该做的第一件事就是获取文件中的所有标记,然后检查它是否存在是令牌的有效排序。
标记化意味着您解析文件并查找所有有效标记并将它们放在有序列表中。您的案例中的有效令牌是以<
开头并以>
结尾的任何字符串长度。您可以安全地丢弃我认为的其他信息吗?如果您有一个Token
类来包含您的令牌类型,那将是最简单的。
一旦你拥有了有序的令牌列表,就会更容易来确定它们是否是一个正确的排序&#39;使用你的堆栈:
is_correct_ordering算法:
For each element in the list
if the element is an open-token, put it on the stack
if the element is a close-token
if the stack is empty return false
if the top element of the stack is a matching close token
pop the top element of the stack
else return false
discard any other token
If the stack is NOT empty, return false
Else return true
当然,拥有合理的Token
类结构会让事情变得简单:
class Token:
def matches(t: Token) -> bool:
pass # TODO Implement
@classmethod
def tokenize(token_string: str) -> Token:
pass # TODO Implement to return the proper subclass instantiation of the given string
class OpenToken:
pass
class CloseToken:
pass
class OtherToken:
pass
这将挑战分为两部分:首先解析所有有效令牌的文件(易于验证,因为您可以手动比较您的有序列表与您在文件中看到的内容),然后验证有序列表是否正确。请注意,在这里,您可以通过将工作委派给子程序来简化您的工作:
def tokenize_file(file) -> list:
token_list = []
while i < len(file):
token_string, token_end = get_token(file[i:])
token_list.append = Token.tokenize(token_string)
i = i + token_end # Skip to the end of this token
return token_list
def get_token(file) -> tuple:
# Note this is a naive implementation. Consider the edge case:
# <img src="Valid string with >">
token_string = ""
for x in range(len(file)):
token_string.append(file[x])
if file[x] == '>':
return token_string, x
# Note that this function will fail if the file terminates before you find a closing tag!
以上应该是这样的:
<html>Blah<meta src="lala"/><body><br/></body></html>
分为:
[OpenToken('<html>'),
OtherToken('<meta src="lala"/>'),
OpenToken('<body>'),
OtherToken('<br/>'),
CloseToken('</body>'),
CloseToken('</html>')]
可以更容易地处理以确定正确性。
显然,这并不能完全解决您的问题,但希望它能帮助您理解您当前所选择的尴尬。