09-词语边界

元字符\b^$一样也是一个位置字符。它也是一个零宽的匹配字符,它匹配的是词语边界。

词语边界可以匹配三种不同的位置:

  • 匹配字符串中第一个字符之前的位置,如果第一个字符属于词语字符(word character)
  • 匹配字符串中最后一个字符之后的位置,如果最后一个字符是词语字符
  • 匹配两个字符之间的位置,如果其中一个是词语字符而另一个不是。

我们可以使用\b匹配字符串中的单词,例如\bword\b可以匹配单词word。单词字符是指那些可以构成单词的字符,一切单词字符以外的字符都称为非单词字符。

事实上哪些字符可以被作为词语字符和你所使用的引擎有很大的关系。在大多数引擎中,字符集缩写\w可以匹配的字符被当做词语字符。Java是一个例外,因为Java中的\b支持Unicode而\w不支持。

大多数引擎使用同一个元字符表示词语的开始和结束。这是因为字符间的任何一个位置都不可能同时成为词语的开始和结尾位置。使用单个元字符合适可以让表达式更加简洁。

由于数字也属于词语字符,所以\b4\b可以匹配到单个出现的数字4。这个正则表达式不会匹配到 “44 sheets of a4”中的任何字符。所以说\b并不是匹配字母序列的边界,而是匹配单词的边界。

\b作用相反的是\B\B可以匹配任何\b不能匹配的位置。也就是说\B匹配的是任何两个词语字符之间的位置,或者任何两个非词语字符之间的位置。

9.1 字符边界的内部原理

让我们来看一下引擎内部是如何匹配表达式\bis\b的,假如我们用这个表达式匹配“This island is beautiful”。引擎首先把第一个token\b和第一个字符T之前的位置匹配,因为\b是一个零宽的匹配,所以\b会匹配T的前一个位置void。由于T是字符串的首个字符、并且T属于词语字符,所以\b可以匹配这个位置。引擎接下来匹配tokeni,由于前一个token是零宽的,所以i和字符T匹配。这一次的匹配没有成功,所以引擎回到正则的第一个token,并且把它和字符h匹配。由于T和h之间不是字符的边界,所以匹配不成功。基于同样的原因h和i之间的位置以及i和s之间的位置也不能和\b匹配。

接下来正则引擎将匹配空格字符。由于当前位置处于字符串的中间,并且占据当前位置的是一个非词语字符而前一个位置是词语字符,所以这一次的匹配是成功的。接下来引擎将tokeni和空格字符匹配,匹配没有成功。

正则引擎又开始新一轮的匹配,这次将token\b和空格和i之间的位置相匹配。由于空格是非词语字符而i是一个词语字符,所以匹配是成功的。接下来的i和s也都匹配成功了。下一步引擎将用\b匹配字符l之前的位置,这一次匹配失败了,因为i和l都是词语字符。之后的sland基于同样的原因,都不能和\b匹配。此时引擎将把token\b和字符串中的第二个空格的前面的位置相匹配,这一次匹配成功了,但是接下来的空格无法和tokeni匹配。

正则引擎重新从i开始匹配,这一次\b和字符i之前的位置匹配成功了。引擎继续向前匹配,发现i和s也匹配成功了。接下来是最后一个token\b,它和字符串中第三个空格之前的位置匹配成功。

至此整个表达式匹配成功了,它匹配了is这个单词。如果你去掉边界符,使用is去匹配这个字符串,你会匹配到this中的is


如果文章出现错误,请给我提Issues - -
Github地址

原文

猜你喜欢

转载自blog.csdn.net/billll/article/details/84900465