捕获分组和非捕获分组

正则表达式中存在有子表达式的情况,子表达式用小括号指定并作为一个整体进行操作。比如,下面代码中的正则表达式'((ABC){2})'将'ABC'作为一个整体重复2次。[大谦MATLAB,dqmatlab点com]

code.matlab
>> a='ABCABCWTU238';
>> m=regexp(a,'((ABC){2})','match')
m =
  1×1 cell 数组
    {'ABCABC'}

使用小括号对正则表达式进行分组时,会自动分配组号。分配组号的原则是从左到右,从外到内。使用组号可以对对应的分组进行反向引用。

下面的代码中,正则表达式r'(WT)\d+\1'匹配原始字符串中前后都是'WT',中间是1个或多个数字的子字符串。注意其中的\1表示小括号内的'WT',这个分组自动分配组号1,使用\1进行反向引用。

code.matlab
>> a='abcWT12389WT';
>> m=regexp(a,'(WT)\d+\1','match')
m =
  1×1 cell 数组
    {'WT12389WT'}

匹配结果'WT12389WT '两端都是'WT',中间全是数字,满足匹配要求。

code.matlab
>> a='abCD123CDbc';
>> m=regexp(a,'(ab)(CD)','tokens')
m =
  1×1 cell 数组
    {1×2 cell}
>> m{1}{1}
ans =
    'ab'
>> m{1}{2}
ans =
   'CD'

上面用小括号定义的分组,每个分组都自动进行编号,匹配结果保存到内存,称为捕获分组。但有时候,我们并不关注匹配到的内容,即分组参与匹配,但没有必要进行捕获,不用在内存中保存匹配到的内容。此时仍然用小括号进行分组,但是在小括号里的最前端加上'?:',这种分组称为非捕获分组。非捕获分组不参与编号,不在内存保存匹配结果,所以能节省内存空间,提高工作效率。

下面给定一个原始字符串,正则表达式为'(?:ab)(CD)',其中两个分组,第1个分组在小括号内的最前端有'?:',为非捕获分组。

code.matlab
>> a='abCD123CDbc';
>> m=regexp(a,'(?:ab)(CD)','tokens')
m =
  1×1 cell 数组
    {1×1 cell}
>> m{1}{1}
ans =
    'CD'

仅返回1个分组结果'CD'。此结果说明第1个分组因为声明为非捕获分组,不参与编号,也不保存。