Perl s /../../无法按预期工作

时间:2013-11-04 20:33:43

标签: regex perl

代码有点复杂,但我简化了一下。我知道我可以很容易地做到这一点:

$svn_module s#.*/##;

然后拉出模块的末尾。但是这里发生了一些奇怪的事情:

#! /usr/bin/env perl
use strict;
use warnings;

my $svn_module = "http://svn.vegicorp.net/svn/trunk/SessionController";
print qq(DEBUG: svn_module = "$svn_module"\n);
$svn_module =~ s#^.*(branches/.+?/)|(trunk)/##;
print qq(DEBUG: svn_module = "$svn_module"\n);

打印:

DEBUG: svn_module = "http://svn.vegicorp.net/svn/trunk/SessionController"
DEBUG: svn_module = "http://svn.vegicorp.net/svn/SessionController"

但是,我在期待:

DEBUG: svn_module = "http://svn.vegicorp.net/svn/trunk/SessionController"
DEBUG: svn_module = "SessionController"

为什么我的替换表达式会删除trunk/,但不会删除trunk/之前的其他字符串?

顺便说一下,添加一组额外的括号有助于:

$svn_module =~ s#^.*((branches/.+?/)|(trunk))/##;

会奏效。

顺便说一句,这是Perl 5.8.8。这是一个服务器,几乎就是我坚持的版本。

3 个答案:

答案 0 :(得分:4)

可能应该是这个

s#^.*(?:branches/.+?/|trunk)/##;

因为,另一种方式是^.*不是一部分的单一交替 第二次交替(匹配的)。

   ^ .* 
   ( branches/ .+? / )
|  
   ( trunk )

编辑:扩展的新正则表达式解释

 ^                       # Beginning of string anchor
 .*                      # Optional match as many as possible non-newline character until ..
 (?:                     # Start non-capture grouping
      branches/ .+? /        # 'branches' plus '/' plus 1 or more chars plus '/'
   |  trunk                  # Or, 'trunk'
 )                       # End grouping

原始正则表达式的等价物是

   ^ .* 
   ( branches/ .+? / )
|  
   ^ .* 
   ( trunk )

答案 1 :(得分:2)

我认为你自己回答了这个问题。 |运算符具有最低优先级,因此添加其他括号是解决方案。

答案 2 :(得分:1)

也许我在这里遗漏了一些东西,大卫,但是为什么不抓住那个最后一部分而不是将所有东西都放到最后一部分你想要得到你想要的东西,为什么不抓住那个最后一部分呢?

use strict;
use warnings;

my $svn_module = "http://svn.vegicorp.net/svn/trunk/SessionController";
my ($end_module) = $svn_module =~ /([^\/]+)$/;
print $end_module;

输出:

SessionController