LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1008|回复: 8

请教这个正则表达是怎么了?

[复制链接]
发表于 2004-5-1 17:35:25 | 显示全部楼层 |阅读模式
大家好,我最近正在学习Perl,现在在正则表达式上遇到了一个问题,百思不得其解,请大家看看我的问题出在什么地方,谢谢!

首先,我有一个标量:
$string = "wake up\neat an apple\ngo to the school";

然后,进行模式匹配:
$string =~ /^(\w+)\s*(.*\s)*(\w+)?$/m;

按照我的想法,生成的反向引用应该如下:
$1 eq 'wake';
$2 eq '';
$3 eq 'up';

但是,实际生成的反向引用如下:
$1 eq 'wake';
$2 eq 'go to the ';
$3 eq  'school';

我想了很久没有明白,Perl的正则表达式会在匹配时吃掉字符,但是在$1和$2之间的字符,为什么没有了?他们是被那个匹配吃掉了?请大家帮我看看好吗?谢谢!
发表于 2004-5-2 09:57:41 | 显示全部楼层
$string =~ /^(\w+)\s*(.*\s)*(\w+)?$/m;
请注意第二对括号后面的"*"号,这表示有任意个(.*\s),而$2捕获的是最后一个。

你可以把这个正则表达式改成:
$string =~ /^(\w+)\s*((.*\s)*)(\w+)?$/m;
看看这里的$2是什么。
 楼主| 发表于 2004-5-2 11:28:57 | 显示全部楼层
谢谢,不过还是不太明白,能不能麻烦你再讲清楚一些?谢谢!
发表于 2004-5-2 13:12:28 | 显示全部楼层
你要注意后面有个/m修饰词
在m//中  
/m修饰词表示  令^和$匹配随后嵌入的\n
发表于 2004-5-2 20:19:50 | 显示全部楼层
在只用m修饰词的情况下:
1、^和$匹配随后嵌入的\n(这点roby已经说了);
2、“.”不匹配“\n”;
3、“\s”匹配“\n”;
如果把表达式改成:
$string =~ /^(\w+)\s*((.*\s)*)(\w+)?$/m;
那么$2就等于:

  1. up
  2. eat an apple
  3. go to the
复制代码

其中"up\n"匹配第一个(.*\s);
"eat an apple\n"匹配第二个(.*\s);
"go to the\n"匹配第二个(.*\s)。

在缺省状态下,perl总是试图匹配尽可能多的次数。
如果你想要:
$1 eq 'wake';
$2 eq '';
$3 eq 'up';
这样的结果,那就把表达式改成:
$string =~ /^(\w+)\s*(.*\s)*?(\w+)?$/m;
这样才行。
 楼主| 发表于 2004-5-3 12:58:31 | 显示全部楼层
明白了,真的是非常感谢!谢谢!
发表于 2004-5-11 09:32:00 | 显示全部楼层
好深呀,看了好久才真正看明白
发表于 2004-5-11 09:32:11 | 显示全部楼层
好深呀,看了好久才真正看明白
发表于 2004-5-11 11:49:28 | 显示全部楼层
分开了都明白,~,可是....一组合,就让人头疼! 唉!
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表