Javascript ?:, ?! 和有什么不一样?和 ?= 在正则表达式中?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10804732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 03:00:44  来源:igfitidea点击:

what is the difference between ?:, ?! and ?= in regex?

javascriptregex

提问by RK Poddar

I searched for the meaning of these expressions but couldn't understand the exact difference between them. This is what they say:

我搜索了这些表达的含义,但无法理解它们之间的确切区别。他们是这样说的:

  • ?:Match expression but do not capture it.
  • ?=Match a suffix but exclude it from capture.
  • ?!Match if suffix is absent.
  • ?:匹配表达式但不捕获它。
  • ?=匹配后缀但将其从捕获中排除。
  • ?!如果后缀不存在则匹配。

I tried using these in simple RegEx and got similar results for all. example: the following 3 expressions give very similar results.

我尝试在简单的 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]+)*
  • [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]+)*

回答by sepp2k

The difference between ?=and ?!is that the former requires the given expression to match and the latter requires it to notmatch. For example a(?=b)will match the "a" in "ab", but not the "a" in "ac". Whereas a(?!b)will match the "a" in "ac", but not the "a" in "ab".

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

The difference between ?:and ?=is that ?=excludes the expression from the entire match while ?:just doesn't create a capturing group. So for example a(?:b)will match the "ab" in "abc", while a(?=b)will only match the "a" in "abc". a(b)would match the "ab" in "abc" andcreate a capture containing the "b".

?:和之间的区别在于从整个匹配?=?=排除表达式,而?:只是不创建捕获组。因此,例如a(?:b)将匹配“abc”中的“ab”,而a(?=b)只会匹配“abc”中的“a”。a(b)将匹配“abc”中的“ab”创建包含“b”的捕获。

回答by anubhava

?:  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

Please check here: http://www.regular-expressions.info/lookaround.htmlfor very good tutorial and examples on lookahead in regular expressions.

请在此处查看:http: //www.regular-expressions.info/lookaround.html有关正则表达式中前瞻的非常好的教程和示例。

回答by freedev

To better understand let's apply the three expressions plus a capturing group and analyse each behaviour.

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

  • ()capturing group- the regex inside the parenthesis must be matched and the match create a capturing group
  • (?:)non capturing group- the regex inside the parenthesis must be matched but doesn't not create the capturing group
  • (?=)positive look ahead- asserts that the regex must be matched
  • (?!)negative look ahead- asserts that it is impossible to match the regex
  • ()捕获组- 括号内的正则表达式必须匹配并且匹配创建一个捕获组
  • (?:)非捕获组- 括号内的正则表达式必须匹配但不会创建捕获组
  • (?=)积极展望- 断言必须匹配正则表达式
  • (?!)负面展望- 断言不可能匹配正则表达式

Let's apply q(u)ito quit. qmatches qand the capturing group umatches u. The match inside the capturing group is taken and a capturing group is created. So the engine continues with i. And iwill match i. This last match attempt is successful. quiis matched and a capturing group with uis created.

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

Let's apply q(?:u)ito quit. Again, qmatches qand the non-capturing group umatches u. The match from the non-capturing group is taken, but the capturing group is not created. So the engine continues with i. And iwill match i. This last match attempt is successful. quiis matched

让我们将q(?:u)i退出。同样,q匹配q并且非捕获组u匹配u。获取来自非捕获组的匹配项,但不创建捕获组。所以引擎继续i。而i将匹配。最后一次匹配尝试成功。qui匹配

Let's apply q(?=u)ito quit. The lookahead is positive and is followed by another token. Again, qmatches qand umatches u. Again, the match from the lookahead must be discarded, so the engine steps back from iin the string to u. The lookahead was successful, so the engine continues with i. But icannot match u. So this match attempt fails.

让我们将q(?=u)i退出。前瞻是正的,后面跟着另一个标记。同样,q匹配qu匹配u。同样,来自前瞻的匹配必须被丢弃,因此引擎从i字符串中退回到u。前瞻成功,因此引擎继续使用i. 但i不能匹配u。所以这次匹配尝试失败了。

Let's apply q(?=u)uto quit. The lookahead is positive and is followed by another token. Again, qmatches qand umatches u. The match from the lookahead must be discarded, so the engine steps back from uin the string to u. The lookahead was successful, so the engine continues with u. And uwill match u. So this match attempt is successful. quis matched

让我们将q(?=u)u退出。前瞻是正的,后面跟着另一个标记。同样,q匹配qu匹配u。来自前瞻的匹配必须被丢弃,因此引擎从u字符串中退回到u。前瞻成功,因此引擎继续使用u. 并且u会匹配u。所以这次比赛尝试是成功的。qu匹配

Let's apply q(?!i)uto quit. Even in this case lookahead is positive (because idoes not match) and is followed by another token. Again, qmatches qand idoesn't matches u. The match from the lookahead must be discarded, so the engine steps back from uin the string to u. The lookahead was successful, so the engine continues with u. And uwill match u. So this match attempt is successful. quis matched

让我们将q(?!i)u退出。即使在这种情况下,前瞻也是肯定的(因为i不匹配)并且后面跟着另一个标记。同样,q匹配q并且i不匹配u。来自前瞻的匹配必须被丢弃,因此引擎从u字符串中退回到u。前瞻成功,因此引擎继续使用u. 并且u会匹配u。所以这次比赛尝试是成功的。qu匹配

So, in conclusion, the real difference between lookahead and non-capturing groups it is all about if you want just test the existence or test and save the match. Capturing group are expensive so use it judiciously.

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

回答by lanzz

Try matching foobaragainst these:

尝试匹配foobar这些:

/foo(?=b)(.*)/
/foo(?!b)(.*)/

The first regex will match and will return "bar" as first submatch — (?=b)matches the 'b', but does not consume it, leaving it for the following parentheses.

第一个正则表达式将匹配并返回“bar”作为第一个子(?=b)匹配-匹配“b”,但不使用它,将其保留在以下括号中。

The second regex will NOT match, because it expects "foo" to be followed by something different from 'b'.

第二个正则表达式将不匹配,因为它期望“foo”后跟与“b”不同的东西。

(?:...)has exactly the same effect as simple (...), but it does not return that portion as a submatch.

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

回答by BlackGlory

The simplest way to understand assertions is to treat them as the command inserted into a regular expression. When the engine runs to an assertion, it will immediately check the condition described by the assertion. If the result is true, then continue to run the regular expression.

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

回答by TeaDrinker

This is the real difference:

这是真正的区别:

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

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

If you dont care the content after "?:" or "?=", "?:" and "?=" are just the same. Both of them are ok to use.

如果你不关心“?:”或“?=”后面的内容,“?:”和“?=”是一样的。两者都可以使用。

But if you need those content for further process(not just match the whole thing. In that case you can simply use "a(b)") You have to use "?=" instead. Cause "?:"will just through it away.

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