Main Content

正则表达式中的前向断言

前向断言

正则表达式有两种类型的环顾断言:前向断言和后向断言。在这两种情况下,断言是一个必须满足才能返回表达式匹配项的条件。

前向断言的形式为 (?=test),可以显示在正则表达式中的任意位置。MATLAB® 从文本的当前位置向前查找测试条件。如果 MATLAB 与测试条件匹配,它将会继续处理表达式的其余部分以找到匹配项。

例如,在指定路径的字符向量中向前查找以找到包含程序文件(此示例中为 fileread.m)的文件夹的名称。

chr = which('fileread')
chr =

    'matlabroot\toolbox\matlab\iofun\fileread.m'
regexp(chr,'\w+(?=\\\w+\.[mp])','match')
ans =

  1×1 cell array

    {'iofun'}

匹配表达式 \w+ 会搜索一个或多个字母数字或下划线字符。每次 regexp 找到与此条件匹配的项时,它都会向前查找反斜杠(通过两个反斜杠 \\ 指定),后跟一个带有 .m.p 扩展名 (\.[mp]) 的文件名 (\w+)。regexp 函数返回符合前向条件的匹配项,即文件夹名称 iofun

重叠匹配项

前向断言不消减文本中的任何字符。因此,您可以使用它们来查找重叠的字符序列。

例如,使用前向搜索并通过匹配后跟五个其他字符的初始字符,在字符向量中查找每一个由六个非空白字符组成的序列:

chr = 'Locate several 6-char. phrases';
startIndex = regexpi(chr,'\S(?=\S{5})')
startIndex =

     1     8     9    16    17    24    25

起始索引与以下短语对应:

Locate   severa   everal   6-char   -char.   phrase   hrases

如果没有前向运算符,MATLAB 将从左至右解析字符向量,并在解析过程中消减该向量。如果找到匹配的字符,regexp 将会记录相应位置并从最新匹配项的位置开始继续解析字符向量。此过程不存在字符重叠。

chr = 'Locate several 6-char. phrases';
startIndex = regexpi(chr,'\S{6}')
startIndex =

     1     8    16    24

起始索引与以下短语对应:

Locate   severa   6-char   phrase

逻辑 AND 条件

使用前向运算的另一种方式是在两个条件之间执行逻辑 AND。此示例最初会尝试找到字符数组(由 normest 函数帮助的前 50 个字符组成)中的所有小写辅音字母。

helptext = help('normest');
chr = helptext(1:50)
chr =

    ' NORMEST Estimate the matrix 2-norm.
         NORMEST(S'

仅仅搜索非元音字母 ([^aeiou]) 不会返回预期的答案,因为输出包含大写字母、空格字符和标点符号:

c = regexp(chr,'[^aeiou]','match')
c =

  1×43 cell array

  Columns 1 through 14

    {' '}    {'N'}    {'O'}    {'R'}    {'M'}    {'E'}    {'S'}    {'T'}    {' '}    {'E'}    {'s'}    {'t'}    {'m'}    {'t'}

  Columns 15 through 28

    {' '}    {'t'}    {'h'}    {' '}    {'m'}    {'t'}    {'r'}    {'x'}    {' '}    {'2'}    {'-'}    {'n'}    {'r'}    {'m'}

  Columns 29 through 42

    {'.'}    {'↵'}    {' '}    {' '}    {' '}    {' '}    {'N'}    {'O'}    {'R'}    {'M'}    {'E'}    {'S'}    {'T'}    {'('}

  Column 43

    {'S'}

重新尝试此操作,并使用前向运算符创建以下 AND 条件:

(lowercase letter) AND (not a vowel)

这一次的结果是正确的:

c = regexp(chr,'(?=[a-z])[^aeiou]','match')
c =

  1×13 cell array

    {'s'}    {'t'}    {'m'}    {'t'}    {'t'}    {'h'}    {'m'}    {'t'}    {'r'}    {'x'}    {'n'}    {'r'}    {'m'}

请注意,使用前向运算符执行 AND 时,您需要将匹配表达式 expr 放在测试表达式 test后面

(?=test)expr or (?!test)expr

另请参阅

| |

相关主题