1

我今天早些时候发布了一个关于同一问题的问题,但由于解决方案是切换库,而我现在遇到了另一个库的问题,所以我想打开另一个问题......希望没关系。

所以我不想匹配以下标记:

<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 的原因。

现在它不再循环,但某些方法也没有执行。

帮助将不胜感激。

4

2 回答 2

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 来伪造它。

于 2013-01-09T13:47:32.800 回答
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)
于 2013-01-09T14:28:19.380 回答