Lookaround正则表达式引擎

时间:2011-01-20 20:11:08

标签: java regex

正则表达式引擎如何在外观方面发挥作用?我的具体查询如下:

如果我输入^(?!ABC)$,那么会查看子串ABC的整个字符串吗?

其次,我如何在一个正则表达式中执行两个操作?假设我想找到一个奇数b和偶数c的字符串?

编辑:我只想谈谈正则表达式;我知道这可以通过其他方式完成。

这就是我正在使用的:

\b(?=[^A]*A([^A]*A[^A]*A)*[^A]*)([^C]*(C[^C]*C[^C]*)*[^C]*)\b

它在CC失败,但只应提取奇数ac的字符串。

4 个答案:

答案 0 :(得分:1)

  

^(?!ABC)$会查看子串ABC的字符串吗?

不,它只与空字符串匹配,它是零宽度负向前瞻。你可以将它用于"^(?!ABC)A..$"匹配ABD,ADC,但不匹配ABC。

  

其次,我如何在一个正则表达式中执行两个操作?假设我想找到一个奇数个b和一个偶数个c的字符串?

写下两个模式,并将第一个模式放在像(?=pat1)pat2

这样的正向前瞻中

答案 1 :(得分:1)

事实证明,你可以用一个普通的正则表达式来做到这一点。它只是不漂亮。

^((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*(b|c((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*b((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*c)((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*$

要理解正则表达式,请绘制一个DFA,其中四个状态排列成正方形,围绕正方形的周边向前和向后链接。水平链接表示消耗B,而垂直链接表示消耗C.在左上方是开始状态,表示具有偶数个C和偶数个B。右上角是接受状态,通过消耗B来达到。通过消耗C从顶部状态(反之亦然)达到底部状态。现在,我们可以进行任何数量的转换来保持我们的Cs的奇偶性。和Bs,我们最终会回到起始状态。然后我们消耗B,将我们带到接受状态。然后,从那里,只要我们保持平价,我们就是好的。两个C保持平价,两个B保持平价。这是(cc|bb)*位。

但你也可以通过走到对面的角落(通过任意顺序的C和B)维持平价,做任意数量的BB / CC,然后回到你所在的角落(再次,无论哪种方式) )。这就是这个问题:((bc|cb)(bb|cc)*(bc|cb))*

所以,我们有((cc|bb)*((bc|cb)(bb|cc)*(bc|cb))*)*,是一组过渡,让我们回到我们开始的地方(称之为noop)。您可以在顶部进行奇数B转换,在这种情况下b将执行,或者在底部,在这种情况下,您需要使用c进入底部,执行另一个noop,然后是你的b,然后是另一个noop,然后c回到顶部。

我应该提到你总是可以使用两个正则表达式并生成一个正则表达式,它只匹配两个表达式匹配的字符串。

答案 2 :(得分:0)

正则表达式只匹配空字符串。

如果你想找到奇数/偶数c和b的数量,那么正则表达式可能不是最好的选择。

答案 3 :(得分:0)

奇怪的c模式看起来像:^[^c]*c[^c]*(c[^c]*c)*[^c]*$不是一个非常好的模式,如果你想为它添加偶数b模式^[^b]*(b[^b]*b)*[^b]*$,结果将完全不可读。< / p>