python – 正则表达式:匹配一个字符串到一个模式(可能不存在)

参见英文答案 > match until a certain pattern using regex                                    3个
我正在尝试使用Python中的正则表达式解析器来解析XML文档(这是一个有限的集合,所以正则表达式很好!),而且我无法正确匹配注释.

这些评论的格式为<! - 这是评论 - >注释本身可以包含各种非字母数字字符(包括’ – ‘)

我想以这样的方式匹配它们,我将注释分解为以下标记:

<! –

这是一个评论

– >

开始标记很容易获得,并且我成功地使用另一个正则表达式获取它,但是注释正则表达式本身变得过于贪婪并从最终标记中抓取 – .我希望这个正则表达式能够抓取不一定包含在注释中的字符串,所以它也应该能够采用< Tag>这是文本< / Tag>并正确返回这是文本.

这是我目前用于文本的正则表达式:

[^<>](?! – >)

结果最终结果是这是一个评论 – 当我只是想要这是一个评论,以便我的其他正则表达式可以抓住 – >.然而,由于’<'的存在,这个正则表达式适用于普通标签.在结束标记上并正确返回这是我之前的示例中的文本. 我知道我不能正确地使用负向前瞻.我在这里做错了什么想法?我已经尝试了[^<>](?= – >),但那时不匹配任何不是这种形式的评论(如普通标签).我认为(?! – >)会在看到该模式时停止匹配,但它看起来不像那样,只是继续匹配,直到看到结束’>’.

为上下文发布一段代码:

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)

这是脚本目前唯一正在做的事情.

最佳答案
你的问题是在[^<>](?! – >)中,只有在这是一个评论后才会尝试前瞻断言 – 已经匹配,当然它会成功,因为没有 – &gt ;在正则表达式引擎结束的位置.

因此,您必须检查字符串的每个位置的前瞻.对此的正确习惯通常是:

(?:(?!-->).)*

或者,在你的情况下

(?:(?!-->)[^<>])*

这匹配除了尖括号之外的任意数量的字符,直到 – >发生或达到字符串的结尾.

转载注明原文:python – 正则表达式:匹配一个字符串到一个模式(可能不存在) - 代码日志