提问者:小点点

为什么积极的前瞻作为第一个捕获组不起作用?


我正在使用以下正则表达式;

((?:_missing_:|_exists_:)[a-z0-9]+)|(([a-z0-9]+)(?=:))

匹配Lucene查询字符串;

_missing_:title age:(>=10 AND < 20) AND age:123 AND _exists_:title123

第一个非捕获组不受尊重,并返回 _missing_:title 而不是 title。使用积极的前瞻会使整个正则表达式无法匹配任何内容。

它应该返回以下数组:;

['title', 'age', 'age', 'title123']

共2个答案

匿名用户

像下面这样更改正则表达式,然后从组索引1和2中获取您想要的字符串。

(?:_missing_:|_exists_:)([a-z1-9]+)|([a-z1-9]+)(?=:)

您不需要在捕获组中包含非捕获组(?:_missing_:|_exists_:)。这就是返回缺少:title而不是title的原因。此外,为[a-z1-9]捕获组就足够了。

演示

匿名用户

你想要的不是一个前瞻,而是一个前瞻:(?

/(?<=_missing_:|_exists_:)([a-z0-9]+)|([a-z0-9]+)(?=:)/

测试。

现在,< code>([a-z0-9] )仅在后面有< code>_missing_:或< code>_exists_:时才匹配,但这些不是匹配的一部分。

第一个非捕获组受到尊重,当你:< code>/((?:_ missing _:| _ exists _:)[a-z0-9])/第一个组跨越整个< code>_missing_:title,第二个组是< code>_missing_:,但不会被捕获,并且< code>title不属于任何组。

但是,即使它没有被捕获,它仍然是匹配的,类似于 /(_missing_:[a-z0-9] )/。你想要的是捕获标题,所以你需要把它放在一个组(中:/(?:_missing_:|_exists_:)([a-z0-9] ))/。现在您有三个组:_missing_:title、_missing_:(未捕获)和标题

您可以将外部组设置为非捕获:/(?:(?:_missing_:| _exists:)([a-z0-9]))/,但没有必要,因为您实际上没有使用它,所以只需删除它:

/(?:_missing_:|_exists_:)([a-z0-9]+)/

现在第一组是title。然而,这仍然是比赛的一部分,这似乎不是你想要的。

要将其从匹配中删除,您需要积极的回溯:

/(?<=_missing_:|_exists_:)([a-z0-9]+)/

此外,由于在第二部分中使用了积极的前瞻,所以没有必要将其放在外部组中,所以只需:

([a-z0-9]+)(?=:)