我在今天早些时候提出了一个关于同一问题的问题,但由于解决方案是切换库,我现在对其他库有问题,因为我打开另一个问题...希望'很好。
所以我不想匹配以下标记:
<text link="no">
...
</text>
我不在乎文本中的内容是什么,文本具有该链接属性。
我现在使用pyparsing如下:
def content_must_not_be_empty_string(tokens):
if tokens[0]=="":
raise ParseException("content cannot be empty")
text_start = Regex('<text[^<]*>')
text_no_start = Regex('<text[^<]*link="no"[^<]*>')
text_no_end = Regex('</text>[ \t\n\r\xa0]*')
text_no_content = SkipTo(text_no_start | text_no_end | text_start)
text_no_content.setParseAction(content_must_not_be_empty_string)
text_no = nestedExpr(text_no_start,text_no_end,text_no_content)
text_no.setParseAction(somemethod)
起初整个事情由于空标记而循环,这就是我添加content_must_not_be_empty的原因。
现在它不再循环,但某些方法也没有执行。
非常感谢帮助。
答案 0 :(得分:2)
严格来说,pyparsing不是XML解析库,但它确实包含一些内置支持,用于从XML和HTML中提取数据,而不是解析整个文档。我并不是说你可以在Regex元素中嵌入正则表达式。相反,请查看使用makeXMLTags或makeHTMLTags:
>>> sample = """<text link="no"> lskdjflskdjf </text>"""
>>> text_start,text_end = makeXMLTags("text")
>>> text_start_no = text_start.copy().setParseAction(withAttribute(link="no"))
>>> expr1 = text_start_no + SkipTo(text_end)('body') + text_end
>>> print expr1.parseString(sample)
['text', ['link', 'no'], False, 'lskdjflskdjf ', '</text>']
>>> print expr1.parseString(sample).dump()
['text', ['link', 'no'], False, 'lskdjflskdjf ', '</text>']
- body: lskdjflskdjf
- empty: False
- endText: </text>
- link: no
- startText: ['text', ['link', 'no'], False]
- empty: False
- link: no
从XML或HTML中提取数据时,这将解决各种意外情况。
现在,如果你实际上有嵌套标签,那么你需要开始钻研到nestedExpr区域。
>>> sample2 = """<text link="no"> lskdjflskdjf<text>more</text> </text>"""
但我仍然鼓励您使用makeXMLTags或makeHTMLTags构建标记结构,而不是使用Regex伪装它。
答案 1 :(得分:0)
这是我现在正在使用的代码:
def content_must_not_be_empty_string(tokens):
if tokens[0]=="":
raise ParseException("content cannot be empty")
text_no_start = Regex('<text[^<]*link="no"[^<]*>')
text_no_end = Regex('</text>[ \t\n\r\xa0]*')
text_no_content = SkipTo(text_no_start | text_no_end)
text_no_content.setParseAction(content_must_not_be_empty_string)
text_no = originalTextFor(nestedExpr(text_no_start,text_no_end,text_no_content), asString="False")
text_no.setParseAction(somemethod)