我正在阅读一份关于正则表达式的Oracle教程,现在看到了捕获组这个主题。尽管参考资料很好,但除了括号表示一个组这一点之外,我仍然很难理解这个主题。以下是我的疑惑:
- 计算表达式中组的意义是什么?
- 什么是非捕获组?
([abc])([def](\d+))
有三个组,所以我知道可以用 \1
、\2
和 \3
来引用它们。请注意,组 3 在组 2 的内部。它们按从左到右开始的位置编号。(foo|bar)
将匹配 "foo"
或 "bar"
。如果你不关心组的内容,可以将其设置为非捕获组(例如:(?:foo|bar)
(具体取决于方言)),以便不使用分配给组的数字。但你也可以不这样做,有时候这样做很方便。\b([a-z])[a-z]*\1\b
然后 \1
将与第一个组捕获的内容相同。当然,它可以用于更强大的操作,但我想你会明白的。(想出相关的例子肯定是最难的部分。)
编辑: 我回答的问题是:
- 计算表达式中组的数量的重要性是什么?
- 有一个特殊的组,称为组-0,表示整个表达式。它不会被 groupCount() 方法报告。为什么?
- 我不理解非捕获组是什么?
- 为什么我们需要反向引用?反向引用的意义是什么?
abcabc
,你想要确定这个字符串的前半部分是否与后半部分匹配。你可以使用一个正则表达式来实现,通过使用捕获组和反向引用。下面是我会使用的正则表达式:(.+)\1
.+
匹配任何字符序列。由于它在括号中,它被分组捕获。 \1
是对第一个捕获组的向后引用,因此它等效于由捕获组捕获的文本。经过一些回溯,捕获组匹配字符串的第一部分,即abc
。现在,向后引用\1
等同于abc
,因此它匹配字符串的第二半部分。整个字符串现在已匹配,因此确认字符串的前半部分与后半部分匹配。
[...]
替换所有{...}
,如果花括号内的文本只包含数字,则可以使用捕获组和向后引用轻松实现,使用正则表达式:{(\d+)}
将其替换为 [\1] 。
正则表达式在字符串 abc {123} 456 中匹配 {123} ,并在第一个捕获组中捕获 123 。回溯引用 \1 现在等同于 123 ,因此使用 [\1] 替换 abc {(\d +)} 会导致 abc [123] 456 。
非捕获组存在的原因是因为组通常具有不仅限于捕获的更多用途。正则表达式(xyz)+ 匹配完全由重复的组 xyz 组成的字符串,例如 xyzxyzxyz 。需要组,因为 xyz + 仅匹配 xy ,然后是重复的 z ,即 xyzzzzz 。使用捕获组的问题在于它们与非捕获组相比略微低效,并且它们占据索引。如果您有一个包含许多组的复杂正则表达式,但只需要在中间某个位置引用单个正则表达式,则最好只引用 \1 ,而不是尝试计算到您需要的那个组。
希望这可以帮助你!
groupCount()
只是让你知道在表达式中指定了多少个捕获组。(?:)
用于不捕获组。例如,如果您需要测试字符串是否包含多个单词之一并且不想在新组中捕获该单词:(?:hello|hi there) world
!== hello|hi there world
。第一个匹配“hello world”或“hi there world”,但第二个匹配“hello”或“hi there world”。^(\d)(?!.*\1)\d+$
将确保字符串中的第一个数字是唯一的。
\1
等),或者在使用的任何正则表达式库中使用它们(例如match.GetGroup(1)
)。然后假设我有一个地方想要匹配三个单词中的一个,但我不关心它是哪一个:...(?:one|two|three)...
我将其设置为非捕获组,以免为其分配编号;只有我感兴趣的内容所在的组才会有编号。 - Biffen