Tag Archive: regular expression

Oct 06

正则表达式之环顾断言(续)

3. 肯定后顾断言(positive look-behind assertion): (?<=pattern) 从当前匹配位置往后(左)看,将当前匹配位置左(后)边的字符串与子模式进行比较,若匹配则成功。 例如,要匹配Perl Hacker(而不是Java Hacker 或者Python Hacker). 即要求Hacker之前必须是单词Perl, 可以这样: /(?< =\bPerl)\s+Hacker/ 测试字符串: He is a Perl Hacker ——–位置——- 0123456789012345678 ———-1——– 可以成功匹配。我们来分析下。 首先,确定当前匹配位置。断言子模式右边的模式成功匹配的位置, 就是当前位置。后面的模式是 /\s+Hacker/ 可知当前匹配位置为12.去掉其后面的字符,将剩下的字符串”He is a Perl”与断言子模式 \bPerl进行比较,结果匹配成功,于是整个模式的成功匹配。 测试字符串: He is just another Java Hacker ——-位置———– 012345678901234567890123456789 ———-1———2——— 则不能匹配。 忽略断言子模式,我们能看出,当前匹配位置为23.去掉位置23之后的字符, 得到”He is just another Java”, 显然不能匹配断言子模式\bPerl,所以不能 匹配。 确定当前匹配位置对于分析前瞻/后顾断言很重要,我们再来分析一个稍微复杂 点的例子。 这里,我们想要匹配跟在单词a后面的Perl …

Continue reading »

Sep 29

正则表达式之环顾断言

在正则表达式中,环顾断言(Look-Around Assertions)属于扩展模式,因为它是零宽度断言(zero-length assertions),所以它的结果只是匹配成功或者失败,而不会记录匹配到的东西。从结果上,环顾断言分为肯定断言(positive assertion)和否定断言(negative assertion)。肯定断言成功的前提是其子模式成功匹配,而否定断言成功的前提是其子模式不匹配。从方向上看,环顾断言又分为前瞻断言(从当前匹配位置向前/右看,look-ahead)和后顾断言(从当前匹配位置往后/左,look-behind)。这里前和后容易搞混,可以这样想,正则表达式是从左到右进行匹配的,从起点(左)出发,往前即是往右走,往后即是往左走。 综合起来,环顾断言共有以下四种情况: 1. 肯定前瞻断言(positive look-ahead assertion): (?=subpattern) 从当前匹配位置往前看,若子模式匹配,则成功。这里有一个来自《精通Perl》第二章,”高级正则表达式”的例子:匹配同时包含单词Wilma和Fred的行(不管顺序如何)。 $_ = "Here come Wilma and Fred!"; print "Matches: $_" if /(?=.*Wilma).*Fred/; 分析这个正则表达式的时候,我们首先要确定当前匹配位置。忽略断言(?=.*Wilma),于是得到模式 .*Fred 成功匹配它之后,当前匹配位置为0,也就是字符串的开头。然后再看断言子模式 .*Wilma 如果这个字符串中包含Wilma,那么匹配成功。注意,由于两个子模式的起点都是字符串的开头,所以无论是 Here come Wilma and Fred 还是 Here come Fred and Wilma,也就是说,不管Fred和Wilma的位置如何,我们的模式都能正确匹配。 2. 否定前瞻断言(negative look-ahead assertion): (?!subpattern) 从当前匹配位置往前看,若子模式不匹配,则成功。例如,要匹配单词hate后面不能是单词you的情况,可以这样 /hate(?!\s+you\b)/ 这个模式可以匹配”I hate him”, “I hate your brother”, 但是不能匹配” …

Continue reading »