代码之家  ›  专栏  ›  技术社区  ›  Jens

环视组中的条件如何在.NET正则表达式中工作?

  •  7
  • Jens  · 技术社区  · 14 年前

    玩弄正则表达式,特别是.NET风格的平衡匹配,我意识到我对引擎内部工作的理解不如我想象的那么好。我会告诉你我的模式为什么会这样!但是拳头。。。

    免责声明: 这个问题纯粹是理论上的问题,这里得到的任何结果都不会被使用,也不会被修改,也不会在生产代码中用来解析HTML。永远。我保证。我确实害怕小马。=)

    A ,如果它不是由 # . 为了演示,我将一直使用字符串 ..A..#..A.. . 这里,第一个 一个 应该匹配。当然,使用 "A(?<!^.*#.*)" ,但我希望在这里使用条件语句,因为它们可以用于平衡匹配和其他很酷的事情。

    我试过的是

    "A(?<=^(#(?<q>)|[^#])*(?(q)(?!)))"
    

    我的解释是:当引擎遇到一个“A”时,它返回到字符串的开头,如果字符是A,则为每个字符向捕获组q添加一个空匹配项。如果q包含匹配项,那么它应该失败。我不明白的是,为什么这个表达式与我的示例字符串中的两个表达式都匹配。

    当我简单地删除lookbehind并匹配整个字符串时,这将起作用:

    "^(#(?<q>)|[^#])*(?(q)(?!))A"
    

    将整个字符串匹配到第一个A,即使第一个组的量词是贪心的。在开头插入“35;”也会导致匹配失败(如所需)。

    谢谢!

    编辑: (?<=(?<q>)(?(q)(?!))). ,它不应与任何字符匹配,而应与所有字符匹配。

    1 回复  |  直到 14 年前
        1
  •  3
  •   Alan Moore Chris Ballance    14 年前

    条件式在平衡匹配中并没有那么有用——或者在其他任何地方,都是如此。;)平衡匹配的工作原理是使用一个命名的捕获组作为堆栈;每当该组匹配某个内容时,匹配的文本就会被推送到堆栈上。还有一些特殊的语法用于弹出堆栈。这里有一个很好的介绍:

    http://blog.stevenlevithan.com/archives/balancing-groups