有什么区别?:,?!和?=在正则表达式?

RK *_*dar 81 javascript regex

我搜索了这些表达式的含义,但无法理解它们之间的确切差异.这就是他们所说的:

  • ?: 匹配表达式但不捕获它.
  • ?= 匹配后缀但将其从捕获中排除.
  • ?! 匹配if后缀不存在.

我尝试在简单的RegEx中使用它们,并获得了类似的结果.示例:以下3个表达式给出非常相似的结果.

  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?!\.[a-zA-Z0-9]+)*
  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?=\.[a-zA-Z0-9]+)*
  • [a-zA-Z0-9._-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9]+)*

sep*_*p2k 116

?=和之间的区别在于?!前者要求给定的表达式匹配,而后者要求它匹配.例如,a(?=b)匹配"ab"中的"a",但不匹配"ac"中的"a".而a(?!b)匹配"ac"中的"a",而不是"ab"中的"a".

?:和之间的区别?=?=从整个匹配中排除表达式?:而不创建捕获组.因此,例如a(?:b)将匹配"abc"中的"ab",而a(?=b)仅匹配"abc" 中的"a".a(b)将匹配"abc"中的"ab" 创建包含"b"的捕获.


anu*_*ava 66

?:  is for non capturing group
?=  is for positive look ahead
?!  is for negative look ahead
?<= is for positive look behind
?<! is for negative look behind
Run Code Online (Sandbox Code Playgroud)

请查看:http://www.regular-expressions.info/lookaround.html,了解非常好的教程和正则表达式中的前瞻示例.

  • 然而,JavaScript并不知道外观. (12认同)

fre*_*dev 15

为了更好地理解,让我们应用三个表达式和一个捕获组并分析每个行为.

  • () 捕获组 - 括号内的正则表达式必须匹配,匹配创建捕获组
  • (?:) 非捕获组 - 括号内的正则表达式必须匹配,但不能创建捕获组
  • (?=) 积极向前看 - 断言正则表达式必须匹配
  • (?!) 负向前看 - 声称不可能匹配正则表达式

让我们将q(u)i退出.q匹配q,捕获组u匹配.获取捕获组内的匹配并创建捕获组.所以引擎继续i.而i将匹配.最后一次匹配尝试成功.qui匹配,创建了一个u的捕获组.

让我们将q(?:u)i退出.同样,q匹配q和非捕获组u匹配u.将执行与非捕获组的匹配,但不会创建捕获组.所以引擎继续i.而i将匹配.最后一次匹配尝试成功.qui匹配

让我们将q(?=u)i退出.前瞻是积极的,后面是另一个令牌.再次,q匹配qu匹配u.同样,必须丢弃前瞻的匹配,因此引擎从i字符串中退回到u.前瞻是成功的,所以引擎继续i.但是i无法与你相提并论.所以这场比赛尝试失败了.

让我们将q(?=u)u退出.前瞻是积极的,后面是另一个令牌.再次,q匹配qu匹配u.必须丢弃前瞻的匹配,因此引擎会从u字符串中退回到u.前瞻是成功的,所以引擎继续u.并且u会匹配.所以这次比赛尝试是成功的.qu匹配

让我们将q(?!i)u退出.即使在这种情况下,前瞻是积极的(因为i不匹配),然后是另一个令牌.再次,q匹配q并且i不匹配u.必须丢弃前瞻的匹配,因此引擎会从u字符串中退回到u.前瞻是成功的,所以引擎继续u.并且u会匹配.所以这次比赛尝试是成功的.qu匹配

因此,总而言之,如果您只想测试存在或测试并保存匹配,前瞻和非捕获组之间的真正区别就在于此.捕获组是昂贵的,所以明智地使用它.

  • 这很有帮助。我认为这应该是公认的答案。 (4认同)
  • @Green 关于lookahead 和其他lookaround 结构要理解的一件重要事情是,虽然它们通过动作来查看它们的子表达式是否能够匹配,但它们实际上并不“消耗”任何文本。这可能有点令人困惑 (3认同)

lan*_*nzz 5

尝试匹配foobar这些:

/foo(?=b)(.*)/
/foo(?!b)(.*)/
Run Code Online (Sandbox Code Playgroud)

第一个正则表达式将匹配并将返回"bar"作为第一个子(?=b)匹配- 匹配'b',但不消耗它,留下它用于以下括号.

第二个正则表达式不匹配,因为它期望"foo"后跟不同于'b'的东西.

(?:...)具有与简单相同的效果(...),但它不会将该部分作为子匹配返回.