位置匹配(\b、 \B 、 ^、 $)

2017-12-14 10:38:43
linefo
1012
最后编辑:linefo 于 2017-12-14 17:49:31


准备好了吗?从这里开始,内容会稍微难理解一点


在学习位置匹配之前,我们要先了解 边界 的问题。

先看下面这个例子(请不要关注我的英语水平):


在上面的例子,正则表达式“car”找到了两个结果。现在我们想把句子变成“have a cartoon dog”,如果按“car”匹配的结果进行替换,句子就会变成:


have a dogtoon dog


这显然跟我们的需求不符合,所以我们必须设置一个 边界 ,让正则表达式只能搜索到car这个单词。


单词边界(\b)


我们用限定符 \b 可以指定单词边界(开始或结尾)

【例子】\bcar\b

(在下面的例子中,单词car的前后都是空格,而空格是分隔单词的字符之一,所以判定为一个单词,而cartoon这个单词,虽然前面是空格,但car后面的字母为t,不符合我们的正则表达式)


更进一步理解单词边界

【例子】\bcar


【例子】car\b



是不是感觉已经理解边界的概念了?那看看下面这个例子

【例子】\b-\b


你是不是以为会匹配到第二个“-”? 

╮(╯▽╰)╭

经过多次测试,我的理解是,就是字母、数字、下划线、(中文)的单词边界是一致的(可由 空格和换行 界定),而 - 的单词边界界定规则和前面这几个是相反的(可能还有其他符号也是如此)。在a-b中,对- 来说,a和b也是边界,而 空格和换行 不能界定它的边界。


补充:文本的开始和结束也是单词的边界,翻上面的例子就能理解这句话了


不匹配单词边界(\B)


先不理 - 了。

正如我们之前看到的 \W、\D 一样,\B 表示 \b 的相反功能,即不匹配单词边界


【例子】\Bf\B



扩展:
\< 和 \> 也会被用来匹配单词的边界,但不是所有环境下都支持这种写法,有兴趣的童鞋可以自己去了解一下



字符串边界(^、$)


先概括一下,^ 匹配一个字符串的开头,$ 匹配一个字符串的结尾。

前面我们说到,单词的边界可以被 空格和换行 界定,而字符串的边界呢?


【例子】^kfc$


看上面的结果,是不是感觉和单词边界差不多?再来看看下面的例子


【例子】在后面加空格的情况

【例子】换行的情况


由上面的例子可以发现,空格和换行 无法界定字符串的边界

经过测试,我的理解是,正则中,字符串的意义是 “整个被处理的文本


通过一个实用的例子,有助于我们了解界定字符串边界的意义


一篇标准的xml文档,标签<?xml ?>作为首行,并且前面允许空白字符,结构类似


<?xml version="1.0" encoding="UTF-8" ?>
......


【例子】<\?xml.*\?>

(<?xml />标签不在首行的情况下,该表达式也会匹配到,这显然不是一个合法的xml文档)


【例子】^\s*<\?xml.*\?>

(\s.*,表示允许零个或多个空白字符,该表达式就达到了我们的要求,非首行的情况下匹配不到)



分行匹配模式(Multiline mode)


这个特性不是所有环境下有支持!
前面说过,空格和换行 无法界定字符串的边界,正则中,字符串的意义是 “整个被处理的文本”。


而通过使用 (?m) 记号,我们可以启用 分行匹配模式, 就是把 换行符 当做字符串分隔符来对待。


【例子】(?m)^aaa&


╮(╯▽╰)╭,我的环境好像不支持这种模式......以后有用到再补这部分内容