《perl语言入门》疑问求教

《perl语言入门》疑问求教

小弟正在学习perl,看书看到这里时,难以理解,书中原文如下:

如果以后需要改变正则表达式,如在brontosaurs burger 上再加入barbecue,我们可以加入“ BBQ ” (含有空格),并且使括号
是非捕捉用的,那么我们需要的部分所对应的内存变量仍为$1。否则,可能每一次在正则表达式中加入括号时,需要改变
内存变量名。
if (/(?:bronto)?saurus (?:BBQ )?(steak|burger)/)
{
print “ Fred wants a $1\n” ;
}

据我理解这个BBQ应该是占位符的作用,但我没看出来它有任何作用,现在模式是/a(?:BBQ )?(b)c/匹配abc,$1是b;那我要捕捉a了,模式改成/(a)(?:BBQ )?(b)c/,$1是a,$2是b,根本做不到让$1永远是b(能做到么,变量捕捉可以自由命名么),这个bbq的用法到底是为什么,请不吝赐教
你一定要这么写
别人也拿你没办法
你应该问的是?:这个东西是干啥的
而不是BBQ是干啥的
?:是noncapture parenthess,就是说匹配的东西是不会捕获的
你举的例子也是错的,争取举例如下:
某天你的文档是
this is test
你可以使用
(\S+)\s+(\S+)\s+(\S+)
匹配
结果
$1 = this
$2 = is
$3 = test

某天你发现打错了,其实应该是
this is  a test
那么你如果用原先那个匹配的话
$1 = this
$2 = is
$3 = a
$3就变成了a
那怎么办呢?
通过
(\S+)\s+(\S+)\s+(?:\S+)\s+(\S+)
这样就能够得到
$3 仍然是test的目的


ps:perl 10中引入了named capture,更好的解决了这个问题

QUOTE:
Instead of remembering numbers such as $1, Perl 5.10 lets us name the captures directly in the regular expression. It saves the text it matches in the hash named %+: the key is the label we used and the value is the part of the string that it matched. To label a match variable, we use (?<LABEL>PATTERN) where we replace LABEL with our own names.* We label the first capture name1 and the second one name2, and look in $+{name1} and
$+{name2} to find their values:
use 5.010;
my $names = 'Fred or Barney';
if( $names =~ m/(?<name1>\w+) (?:and|or) (?<name2>\w+)/ ) {
say "I saw $+{name1} and $+{name2}";
}

感谢你的回帖,我看书很认真,不会不明白非捕获匹配的,我问的不是语法上的意义,我以为作者在使用某种技巧让模式和程序低耦合。。看来他只不过是把原文上一段内容又讲了一遍,再次感谢你最后贴的那个东西,太酷了,顺便问一下在逆向引用的时候还是要继续\1么,我用的是5。8
那我还是贴全了吧

QUOTE:
Now that we have a way to label matches, we also need a way to refer to them for back
references. Previously, we used either \1 or \g{1} for this. With a labeled group, we can
use the label in \g{label}:
use 5.010;
my $names = 'Fred Flinstone and Wilma Flinstone';
if( $names =~ m/(?<last_name>\w+) and \w+ \g{last_name}/ ) {
say "I saw $+{last_name}";
}
We can do the same thing with another syntax. Instead of using \g{label}, we use
\k<label>:†
use 5.010;
my $names = 'Fred Flinstone and Wilma Flinstone';
if( $names =~ m/(?<last_name>\w+) and \w+ \k<last_name>/ ) {
say "I saw $+{last_name}";
}

不过perl 5.8就别想了
3q