正则表达式引擎在环视方面如何工作?我的具体查询如下:
如果我输入 ^(?!ABC)$
,它会在整个字符串中查找子字符串 ABC 吗?
其次,我如何在一个正则表达式中执行两个操作?假设我想找到一个包含奇数个 b
和偶数个 c
的字符串?
编辑:我只想谈论正则表达式;我知道这可以通过其他方式来完成。
这就是我正在使用的:
\b(?=[^A]*A([^A]*A[^A]*A)*[^A]*)([^C]*(C[^C]*C[^C]*)*[^C]*)\b
它在 CC
上失败,但应该只提取带有奇数 a
和 c
的字符串。
最佳答案
事实证明,您可以使用普通正则表达式来完成此操作。只是不太漂亮。
^((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 从顶部状态到达的(反之亦然)。现在,我们可以进行任意数量的转换,以保持 C 的奇偶性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
即可)或在底部(在这种情况下您需要使用 c
到达底部)进行奇怪的 B 过渡>,执行另一个 noop,然后让您的 b
,然后另一个 noop,然后将 c
回到顶部。
我应该提到,您始终可以采用两个正则表达式并生成一个仅匹配这两个表达式都匹配的字符串的正则表达式。
关于java - Lookaround 正则表达式引擎,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4752032/