现在的位置: 首页 > 综合 > 正文

简单入门正则表达式 – 第七章 字符串、行和词边界

2014年02月02日 ⁄ 综合 ⁄ 共 4087字 ⁄ 字号 评论关闭
文章目录

一、再谈元字符^

在正则表达式中,有一类专门用于限定匹配位置的原字符,“^”就是其中的一个。那具体是如何限定匹配位置的呢?先让我们看一个小例子:

北国风光,千里冰封,万里雪飘。 望长城内外,惟余莽莽; 大河上下,顿失滔滔。 山舞银蛇,原驰蜡象,欲与天公试比高。 须晴日,看红装素裹,分外妖娆。 江山如此多娇,引无数英雄竞折腰。 惜秦皇汉武,略输文采; 唐宗宋祖,稍逊风骚。 一代天骄,成吉思汗,只识弯弓射大雕。 俱往矣,数风流人物,还看今朝。

对于上面的文本,要提取出以“山”开头的句子。我们先构造一个以“山”字开头的正则表达式山.+,然后进行匹配操作,结果有两句被匹配:山舞银蛇,原驰蜡象,欲与天公试比高。江山如此多娇,引无数英雄竞折腰。

我们再尝试使用一个含有行边界的正则表达式^山.+来进行匹配,结果只有:山舞银蛇,原驰蜡象,欲与天公试比高。元字符“^”限定正则表达式要匹配的内容必须是从行首进行。当正则表达式^山.+开始进行匹配操作时,正则表达式引擎首先执行位置匹配,如果当前位置是行首,就进行“山”字的匹配,以此类推。

细心的读者可能已经观察到,上面的多行模式(Multiline)选项已经被选中了。如果不采用多行模式的话,从第一句“北国风光”开始到最后一句“还看今朝”,只会当作一行数据来处理。只有在多行模式下,元字符“^”才能发挥更多的作用。

二、元字符$

万事都要有始有终,既然行首有对应的元字符,也就少不了行尾元字符“$”。下面是利用正则表达式.+$作出来的结果。

错误

其中.+代表匹配任意字符,重复一次到更多次,元字符“$”确定了匹配的终止条件是到达行尾。不要忘记,匹配的模式还是多行(Multiline)。

三、同时使用原字符“^”和“$”

在做 Web 开发对页面上的数据进行校验时,经常要把元字符“^”和“$”结合起来使用,这样做的目的是防止部分匹配。比如说用/w{6,12}验证一个长度介于 6 至 12 的密码:

if (!password.match('')) { ... }

虽然按照/w{6,12}的匹配原则确实跟我们预想的一样,但用户录入的 13 位长数据也是合法的。其中的原因就是/w{6, 12} 只是说匹配在 12 位之内,而正则表达式只寻找能匹配上的内容,对于匹配不上的内容会被它忽略掉,所以 match 方法找到了匹配内容后,就报告它的匹配结果,但并不告诉程序员它是部分匹配还是全部匹配。

四、空行的匹配

在使用元字符“^”和“$”时有一种特殊的情况,在这种情况下我们不与任何字符作匹配操作,单单使用^$来进行位置匹配。“^”与行首匹配,“$”与行尾匹配,其间没有任何字符,所以被匹配的内容就是一个空行。下图是在 EmEditor 中做的实验结果,如要正确地匹配,先要把换行设置作如下调整。

当然,对于有些编辑器或设置的问题,^$的表现情况有可能不太一样,这时的非可见字符“/r”、“/n”等也许会被计算在内,所以要使用^/n$^/r/n$才可能正确地找到空行。

五、辨识词界(/<、/>、/b)

行界学习完了,下面该学习更小的位置匹配单位—词界。在谈论词界之前,先让我们想一想,什么是词呢?在我们常用的编辑器的搜索功能中,常常会出现“只搜索单词”或“Match whole word”字样,这时我们检索出来的内容总是一些连续地无间隔字符,这可能是最简单的理解了。在正则表达式中,把连续地字符组合称为词。这些字符不能是符号或标点等,其中有一个特殊的字符下划线“_”,它也被认为是组成词的合法字符,所以,像“Hello”、“你好”、“split_by_underline”等,都可以被认为是词。

说了这么多,那到底什么是词界呢?词界就是两个位置,一个位于连续字符之前,另一个位于连续字符之后。在正则表达式中,可以利用词界把要匹配的内容规定在一个词的范围内,这样就能避免与另一个词的部分字符相匹配。通常情况下,词界是不是前后的,只用一个元字符“/b”来表示。但有些正则引擎中,是可以区分词界的前后位置的,分别使用“/<”和“/>”来表示。

现在尝试用正则表达式in在下面的句子中搜索一下单词“in”,结果有两项匹配内容。

Education is what you have left when you have forgotten everything you learned in school. - Albert Einstein, 1936

显然这不是我们想要的结果,那么让我们用词界来试试,重新构造正则表达式/bin/b,这次的结果跟我们预想的一样,只有单词“in”被匹配。

Education is what you have left when you have forgotten everything you learned in school. - Albert Einstein, 1936

回过头来再考虑一下元字符“/<”和“/>”。“/<”与一个词的首字母之前的位置相匹配,当我们构造正则表达式/<词时,它就能与以“词”字开头的单词首字符相匹配,但如何我们把“/<”和“词”的位置互换构造词/<,它的含义又是什么呢?这次字符“词”就应该与以“词”结尾的单词相匹配了。

打开 Windows 控制台,我们用 findstr 命令做个小实验。首先键入findstr /?命令,从帮助的内容来看,该命令所使用的词界元字符就是“/<”和“/> ”。其中本书所用的术语“词界”与命令帮助显示的内容虽不相同,但含义一样。

在 C 盘下准备如下文件,然后用命令findstr /n "our" "C:/Users/KNIGHTRCOM/Documents/RegexTest.txt" 来进行查找。其中 findstr 后的“n” 选项表示要将找到符合条件的行的号给打印出来,“our”是我们要查找的内容,最后一个字符串代表要在哪个文件中进行查找。

查找过程分为三步,首先按照普通字符的查找方式,只录入“our”,匹配的行是5、6、9;然后我们用“/<”进行限定,没有以字母“o”开头的单词“your”被过滤掉了;再进一步对“our”进行限定,用/<our/>严格匹配单词“our”,这次只有第 5 行被检索出来。

【上篇】
【下篇】

抱歉!评论已关闭.