使用正则表达式,特别是.NET风格的平衡匹配,我发现我意识到我不理解引擎的内部工作方式,就像我想的那样好。我会嘲笑我的模式为什么会这样做的任何输入!但是拳头......
免责声明:此问题纯粹是理论上的,此处获得的任何结果都不会在生产代码中使用或修改并用于解析HTML。永远。我承诺。我确实害怕小马。 =)
现在我的问题。我会尝试匹配字母A
,如果它不在#
之前。为了演示,我将一直使用字符串..A..#..A..
。在这里,应匹配第一个A
。当然,使用"A(?<!^.*#.*)"
这是一项非常简单的任务,但我希望在这里使用条件,因为它们可以用于平衡匹配和其他很酷的事情。
我尝试的是
"A(?<=^(#(?<q>)|[^#])*(?(q)(?!)))"
我解释它的方式是:当引擎遇到“A”时,它返回到字符串的开头,并且对于每个字符,如果字符是#,则向捕获组q添加空匹配。如果q包含匹配,它应该失败。我不明白的是为什么这个表达式与我的样本字符串中的As匹配。
当我简单地删除lookbehind并匹配整个字符串时,这有效:
"^(#(?<q>)|[^#])*(?(q)(?!))A"
匹配整个字符串直到第一个A,即使第一个组的量词是贪婪的。在开头插入“#”也会导致匹配失败(根据需要)。
那么:如何环顾群体,在其中命名捕捉群体和条件一起玩?
谢谢!
修改:在(?<=(?<q>)(?(q)(?!))).
中可以更容易地看到此问题,该问题不应与任何字符匹配,但会匹配所有字符。
答案 0 :(得分:3)
条件在平衡匹配中并没有那么有用 - 或者在其他任何地方都是如此。 ;)平衡匹配通过使用命名捕获组作为堆栈来工作;每当该组匹配某些内容时,匹配的文本就会被压入堆栈。弹出堆栈也有特殊的语法。这是一个很好的介绍: