`
java-mans
  • 浏览: 11467977 次
文章分类
社区版块
存档分类
最新评论

正则习点 --- 13

 
阅读更多

4.5.6 Possessive Quantifiers andAtomic Grouping

那么,仍然来考虑‘.625’的例子,想想我们真正的目的。我们知道,如果匹配能够进行到「(\.\d\d[1-9]?)\d+」中标记的位置,我们就不希望进行回溯。

那么,如果我们能够避免这些备用状态呢?(也就是在[1-9]进行尝试之前,放弃「?」保存的状态)如果没有退路,「1-9」的匹配就不会交还。而这就是我们需要的!

4.5.6.1 Atomic grouping with「(?>…)」

在固化分组匹配结束时,他已经匹配的文本已经固化为一个单元,只能作为整体而保留或放弃。

所以回溯永远也不能选择其中的状态(至少是,当此结构匹配完成时,“锁定(locked in)”在其中的状态)。

示例如下:

#! /usr/bin/perl -w

$price = 9.436;

#$price =~ s/(\.\d\d[1-9]?)\d+/$1/;
# $price =~ s/(\.\d\d[1-9]?)\d*/$1/;
# atomic grouping
$price =~ s/(\.\d\d(?>[1-9])?)/$1/;

print $1;

执行结果:

$perl mre45_32.pl

.436

加上「\d+」后,

执行结果:

$perl mre45_32.pl

Useof uninitialized value $1 inprint at mre45_32.pl line 10.

因为没有能够回溯的备用状态,整体匹配也就失败,‘.436’不需要处理,而这正是我们期望的。

固化分组会放弃某些可能的路径。

放弃备用状态可能会导致的结果:

l毫无影响 如果在使用备用状态之前能够完成匹配,固化分组就不会影响匹配。

l导致匹配失败

l改变匹配结果

l加快报告匹配失败的速度

4.5.7 Possessive Quantifiers, ?+, *+, ++, and {m, n}+

占有优先量词与匹配优先量词很相似,只是他们从来不交还已经匹配的字符。

实际上占有优先量词与固化分组的匹配结果完全一样,只是写起来更加方便而已(而且更加高效)。

修改后的示例:

#! /usr/bin/perl -w

$price = 9.436;

#$price =~ s/(\.\d\d[1-9]?)\d+/$1/;
# $price =~ s/(\.\d\d[1-9]?)\d*/$1/;
# atomic grouping
# $price =~ s/(\.\d\d(?>[1-9])?)d+/$1/;

# Possessive Quantifers
$price =~ s/(\.\d\d[1-9]?+)^\d+/$1/;	# Prohibit Match

#price =~ s/(\.\d\d[1-9]?+)/$1/;		# Match

print $1;


4.5.8 The Backtracking of Lookaround

在NFA的世界中包含了备用状态和回溯,环视是怎么实现的?

首先,我们要明白环视结构不会去包含备用状态和回溯!

包含了这两个的是子表达式!

然后,

那我们看,子表达式匹配成功时:

肯定型环视会认为自己匹配成功;而否定环视会认为匹配失败。在任何一种情况下,因为关注的只是匹配存在与否,此匹配尝试所在的“世界”(子表达式),包括在尝试中创造的所有备用状态,都会被放弃。

子表达式匹配失败时:

肯定型环视会认为自己匹配失败;而否定环视会认为匹配成功。

最后,我们知道环视、固化分组、占有优先量词他们是一样的!

4.5.8.1 Mimicking atomic grouping with positive lookahead

举例来说,比较「(?>\w+):」和「^(?=(\w+))\1:」

Unlike atomic grouping, the match word isnot included as part of the match (that’s the whole of lookahead), but the worddoes remain captured.

但与固化分组不一样的是,虽然此时确实捕获了这个单词,但是它不是全局匹配的一部分(这就是环视的意义)。

4.5.9 Is Alternation Greedy?

多选结构「…|…|…」既不是匹配优先的,也不是忽略优先的,而是按顺序排列的。

4.5.10 Taking Advantage of Ordered Alternation

要记住的是,如果多选分支是有序的,而能够匹配同样文本的多选分支又不只一个,就要小心安排多选分支的先后顺序。

4.5.10.1 Ordered alternation pitfalls

拆分日期的例子:

使用「Jan(0?[1-9]|[12][0-9]|3[01])」匹配‘Jan 31 is Dad’s birthday’,结果如何呢?我们希望获得的当然是‘Jan 31’,但是有序多选分支只会捕获‘Jan 3’。

所以我们用「Jan([12][0-9]|3[01]|0?[1-9])」可以解决这个问题。但是,看这个表达式很是不好理解~~



分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics