Javascript正则表达式中被动组的目的是什么?
被动组以问号冒号开头: (?:group)
换句话说,这两件事看起来是一样的:
"hello world".match(/hello (?:world)/)
"hello world".match(/hello world/)
Run Code Online (Sandbox Code Playgroud)
在什么情况下你需要非捕获组?为什么?
Ale*_*rov 16
一个捕获组在正则表达式实际上已经2不同的目标(如名称"捕获组"本身建议):
分组 - 如果您需要将一个组视为单个实体,以便将一些内容应用于整个组.
可能最简单的例子是包括可选的字符序列,例如"foo",可选地后跟"bar",正则表达式:( /foo(bar)?/
捕获组)或/foo(?:bar)?/
(非捕获组).请注意,尾随?
应用于整个组(bar)
(bar
在这种情况下由一个简单的字符序列组成).如果您只是想检查输入是否与正则表达式匹配,那么无论您使用捕获组还是非捕获组都无关紧要 - 它们的行为相同(除非非捕获组稍快一些).
捕获 - 如果您需要提取输入的一部分.
例如,你想从一个输入中获得一些兔子,例如"农场包含8头奶牛和89头兔子"(我不知道英语不是很好).正则表达式可能是/(\d+)\s*rabbits\b/
.成功匹配后,您可以从JavaScript代码(或任何其他编程语言)获取捕获组匹配的值 .
在此示例中,您有一个捕获组,因此您可以通过其索引访问它0
(有关详细信息,请参阅此答案).
现在想象你想确保"地方"被称为"农场"或"牧场".如果不是这样,那么你不想提取兔子的数量(用正则表达式 - 你不希望正则表达式匹配).
所以你重写你的正则表达式如下:/(farm|ranch).*\b(\d+)\s*rabbits\b/
.正则表达式本身就可以工作,但是你的JavaScript被破坏了 - 现在有两个捕获组,你必须更改你的代码以获得第二个捕获组的内容以获得兔子的数量(即将索引从0改为1).第一组现在包含字符串"farm"或"ranch",您不打算提取它.
一个非捕获组来救援:/(?:farm|ranch).*\b(\d+)\s*rabbits\b/
.它仍然匹配"农场"或"牧场",但不捕获它,因此不会移动后续捕获组的索引.您的JavaScript代码可以正常工作而无需更改.
该示例可能过于简单,但考虑到您拥有一个包含许多组的非常复杂的正则表达式,并且您希望仅捕获其中的少数几个.非捕获组真的很有帮助 - 您不必计算所有组(仅捕获组).
此外,非捕获组用于文档目的:对于读取代码的人,非捕获组表示您对提取内容不感兴趣,您只是想确保它匹配.
捕获组是打破SoC原则的典型示例.此语法构造有两个不同的用途.随着问题变得明显,引入了另外的构造(?:
)以禁用两个特征中的一个.
这只是一个设计错误.也许缺乏"免费特殊角色"扮演了它的角色......但它仍然是一个糟糕的设计.
正则表达式是一个非常古老,强大且广泛使用的概念.出于向后兼容性的原因,现在不太可能修复这个漏洞.这只是关注点分离重要性的一个教训.
非捕获与"正常"(捕获)组只有一个区别:它们不需要正则表达式引擎记住它们匹配的内容.
用例是有时你必须(或应该)使用一个组,不是因为你对它所捕获的内容感兴趣而是出于语法原因.在这些情况下,使用非捕获组而不是"标准"捕获组是有意义的,因为它不太占用资源 - 但如果您不关心它,捕获组将以完全相同的方式运行.
您的具体示例并不能很好地使用非捕获组,因为这两个表达式完全相同.一个更好的例子可能是:
input.match(/hello (?:world|there)/)
Run Code Online (Sandbox Code Playgroud)
除了上面的答案之外,如果您正在使用String.prototype.split()
并且使用捕获组,则输出数组包含捕获的结果(请参阅 MDN)。如果您使用不会发生的非捕获组。
var myString = 'Hello 1 word. Sentence number 2.';
var splits = myString.split(/(\d)/);
console.log(splits);
Run Code Online (Sandbox Code Playgroud)
输出:
["Hello ", "1", " word. Sentence number ", "2", "."]
Run Code Online (Sandbox Code Playgroud)
而换/(\d)/
为/(?:\d)/
在结果:
["Hello ", " word. Sentence number ", "."]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4970 次 |
最近记录: |