【发布时间】:2013-06-09 22:27:19
【问题描述】:
我正在尝试使用 Python 中的正则表达式标记器解析 XML 文档(这是一个有限集,所以正则表达式就可以了!),但我无法正确匹配 cmets。
这些 cmets 的格式为 <!--This is a comment--> 形式,其中注释本身可以包含各种非字母数字字符(包括“-”)
我想以这样一种方式匹配它们,将评论分成以下标记:
<!--
This is a comment
-->
开始标记很容易获得,我用另一个正则表达式成功地抓住了它,但是评论正则表达式本身变得太贪婪并从结束标记中抓取--。不过,我希望这个正则表达式能够获取不一定包含在注释中的字符串,因此它也应该能够采用 <Tag>This is text</Tag> 并正确返回 This is text。
这是我目前用于文本的正则表达式:
[^<>]+(?!-->)
最终结果是This is a comment--,而我只想要This is a comment,以便我的其他正则表达式可以获取-->。这个正则表达式确实适用于普通标签,但是,由于结束标签上存在“This is text。
我知道我不能正确使用负前瞻。关于我在这里做错了什么的任何想法?我试过[^<>]+(?=-->),但是这与任何不是这种形式的评论(如普通标签)不匹配。我认为(?!-->) 在看到该模式时会停止匹配,但它似乎不像那样工作,只是继续匹配直到它看到结尾 '>'。
为上下文贴一段代码:
xml_scanner = re.Scanner([
(r" ", lambda scanner,token:("INDENT", token)),
(r"<[A-Za-z\d._]+(?!\/)>", lambda scanner,token:("BEGINTAG", token)),
(r"<\/[A-Za-z\d._]+(?!\/)>", lambda scanner,token:("ENDTAG", token)),
(r"<[A-Za-z\d._]+\/>", lambda scanner,token:("INLINETAG", token)),
(r"<!--", lambda scanner,token:("BEGINCOMMENT", token)),
(r"-->", lambda scanner,token:("ENDCOMMENT", token)),
(r"[^<>]+(?!-->)", lambda scanner,token:("DATA", token)),
(r"\r$", None),
])
for line in database_file:
results, remainder = xml_scanner.scan(line)
这是脚本目前唯一要做的事情。
【问题讨论】:
-
通过在结果中包含
--,正则表达式确保匹配没有被-->...comment跟在另一方面,是 后面跟着-->,所以你的结果不能以此结尾。 -
啊。有没有办法让它检测到整个模式而不包括它?
标签: python regex negative-lookahead