Javascript 之间的区别:?!然后呢=

Javascript 之间的区别:?!然后呢=,javascript,regex,Javascript,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-]+(?:\

我寻找这些表达的意思,但无法理解它们之间的确切区别

他们是这么说的:

  • ?:
    匹配表达式,但不捕获它
  • ?=
    匹配后缀,但将其从捕获中排除
  • 匹配
我尝试在简单的正则表达式中使用这些函数,得到了类似的结果

例如:以下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]+)*
?:用于非捕获组
?=表示积极的前瞻性
?!  是消极的前瞻
?

请查看此处:有关正则表达式中的前瞻性的非常好的教程和示例。

请尝试将
foobar
与以下内容进行匹配:

/foo(?=b)(.*)/
/foo(?!b)(.*)/
第一个正则表达式将匹配并返回“bar”,因为第一个子匹配-
(?=b)
与“b”匹配,但不使用它,将其保留在下面的括号中

第二个正则表达式将不匹配,因为它希望“foo”后面跟着与“b”不同的内容


(?:…)
与simple
(…)
具有完全相同的效果,但它不会将该部分作为子匹配返回。

之间的差异
是指前者要求给定表达式匹配,而后者要求它不匹配。例如
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”的捕获。

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

  • ()
    捕获组-括号内的正则表达式必须匹配,匹配项将创建捕获组
  • (?:)
    非捕获组-括号内的正则表达式必须匹配,但不创建捕获组
  • (?=)
    正向前瞻-断言必须匹配正则表达式
  • (?!)
    负前瞻-断言不可能匹配正则表达式
让我们应用
q(u)i
退出
q
匹配q,捕获组
u
匹配u。获取捕获组内的匹配并创建捕获组。因此,发动机继续执行
i
。和
i
将匹配i。最后一次比赛成功了。qui匹配,并创建一个带有u的捕获组

让我们应用
q(?:u)i
退出。同样,
q
匹配q,而非捕获组
u
匹配u。将获取非捕获组中的匹配项,但不会创建捕获组。因此,发动机继续执行
i
。和
i
将匹配i。最后一次比赛成功了。奎是匹配的

让我们应用
q(?=u)i
退出。向前看是肯定的,后面跟着另一个标记。同样,
q
与q匹配,
u
与u匹配。同样,必须放弃来自前瞻的匹配,因此引擎从字符串中的
i
后退到u。前瞻成功,因此引擎继续执行
i
。但是
i
不能匹配u。所以这次比赛失败了

让我们应用
q(?=u)u
退出。向前看是肯定的,后面跟着另一个标记。同样,
q
与q匹配,
u
与u匹配。必须放弃来自前瞻的匹配,因此引擎从字符串中的
u
后退到u。前瞻成功,因此引擎继续执行
u
。和
u
将匹配u。所以这次比赛是成功的。曲是匹配的

让我们应用
q(?!i)u
退出。即使在这种情况下,向前看也是正的(因为
i
不匹配),后面跟着另一个标记。同样,
q
与q匹配,
i
与u不匹配。必须放弃来自前瞻的匹配,因此引擎从字符串中的
u
后退到u。前瞻成功,因此引擎继续执行
u
。和
u
将匹配u。所以这次比赛是成功的。曲是匹配的


因此,总而言之,前瞻组和非捕获组之间的真正区别在于您是想测试是否存在,还是想测试并保存匹配。捕获组非常昂贵,所以要明智地使用它。

理解断言的最简单方法是将它们视为插入正则表达式的命令。 当引擎运行到断言时,它将立即检查断言描述的条件。
如果结果为真,则继续运行正则表达式。

这是真正的区别:

>>> re.match('a(?=b)bc', 'abc')
<Match...>
>>> re.match('a(?:b)c', 'abc')
<Match...>

# note:
>>> re.match('a(?=b)c', 'abc')
None
重新匹配('a(?=b)bc','abc') >>>关于匹配('a(?:b)c','abc') #注: >>>关于匹配('a(?=b)c','abc') 没有一个
如果你不在乎“?:”或“?=”之后的内容,“?:”和“?=”是一样的。它们都可以使用


但是,如果您需要这些内容进行进一步的处理(不仅仅是匹配整个内容。在这种情况下,您可以简单地使用“a(b)”),那么您必须使用“?=”。原因“?:”将通过它消失。

请向我们展示您的测试用例。他们不应该给出相同的结果
>>> re.match('a(?=b)bc', 'abc')
<Match...>
>>> re.match('a(?:b)c', 'abc')
<Match...>

# note:
>>> re.match('a(?=b)c', 'abc')
None