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

Jen*_*ens 7 c# regex theory

使用正则表达式,特别是.NET风格的平衡匹配,我发现了一点,我意识到我不理解引擎的内部工作方式和我想的那样好.我会嘲笑我的模式为什么会这样做的任何输入!但拳头......

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

现在我的问题.我会尝试匹配这封信A,如果它没有先于#.为了演示,我总是使用字符串..A..#..A...在这里,第一个A应该匹配.当然,这是一个非常容易使用的任务"A(?<!^.*#.*)",但是我希望在这里使用条件,因为它们可以用于平衡匹配和其他很酷的东西.

我尝试的是

"A(?<=^(#(?<q>)|[^#])*(?(q)(?!)))"
Run Code Online (Sandbox Code Playgroud)

我解释它的方式是:当引擎遇到"A"时,它返回到字符串的开头,并且如果字符是#,则对于每个字符向捕获组q添加空匹配.如果q包含匹配,它应该失败.我不明白的是为什么这个表达式匹配我的样本字符串中的As.

当我简单地删除lookbehind并匹配整个字符串时,这有效:

"^(#(?<q>)|[^#])*(?(q)(?!))A"
Run Code Online (Sandbox Code Playgroud)

匹配整个字符串直到第一个A,即使第一个组的量词是贪婪的.在开头插入"#"也会导致匹配失败(根据需要).

所以:如何环顾群体,在其中命名捕捉群体和条件一起玩?

谢谢!

编辑:这个问题可以更容易看到(?<=(?<q>)(?(q)(?!))).,它不应该匹配任何字符,但匹配一切.

Ala*_*ore 3

就这一点而言,条件在平衡匹配或其他任何地方实际上并没有那么有用。;) 平衡匹配通过使用命名捕获组作为堆栈来工作;每当该组匹配某些内容时,匹配的文本就会被推入堆栈。还有用于弹出堆栈的特殊语法。这是一个很好的介绍:

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