问号的作用

可选项


问号使正则表达式中的前一个标记为可选。colou?r可以匹配colour和color 。我们称?为量词。     

通过使用括号将它们组合在一起,然后将问号放在右括号的后面,可以使多个标记成为可选标记。例如:Nov(ember)?匹配可以匹配Nov和November。     

我们可以通过包含多个问号来编写有许多选择方案的正则表达式。Feb(ruary)?23(rd )?可以匹配February 23rd,February 23,Feb 23rd和Feb 23。 

我们也可以使用花括号将某些内容设置为可选。colou{0,1}rcolou?r 。POSIX BRE和GNU BRE不支持这两种语法。它们要求在花括号前使用反斜杠,这样花括号才有特殊的含义:colou\{0,1\}r 。          

正则表达式的重要概念:贪婪


问号?是从开始到现在引入的第一个贪婪的元字符。问号为正则表达式引擎提供了两种选择:尝试匹配问号所适用的部分,或者不尝试匹配。引擎始终尝试匹配该部分。仅当这导致整个正则表达式失败时,引擎才会尝试忽略问号?适用的部分。 

如果我们将正则表达式Feb 23(rd)?应用到字符串Tommorow is Feb 23rd,2021,始终是匹配Feb 23rd,而不是Feb 23。这是因为?是贪婪的,但是有趣的事情是,虽然问号?是贪婪的,但是问号?也有关闭贪婪的功能。我们可以通过在第一个问号之后放置第二个问号来使问号变得懒惰(即关闭贪婪性)。       

正则表达式引擎内核


让我们将正则表达式colou?r应用于字符串I know that colonel likes the color green。   

正则表达式中的第一个标记是c 。它成功匹配的第一个位置是在colonel 中的c。引擎继续前进,发现o匹配o ,l匹配l ,另一个o匹配o 。然后引擎检查u是否匹配n 。这失败了。但是,问号?告诉正则表达式引擎不匹配u也是可以接受的。因此,引擎向前跳到下一个正则表达式token:r 。但这也无法匹配n 。现在,引擎只能得出结论,整个正则表达式不能在colonel的第一个字符c处匹配。因此,引擎再次尝试将c与colonel的第一个o匹配。                             

一系列的失败后,c在color的开始处匹配到字符c,然后是o,l和o匹配以下字符。现在,引擎检查u是否匹配r 。这失败了。问号允许引擎以r继续。这与r匹配,最终引擎报告正则表达式成功匹配了我们字符串中的color。   

查看笔记

扫码一下
查看教程更方便