简体   繁体   English

Perl s /../../无法正常工作

[英]Perl s/../../ not working as expected

The code is a bit convoluted, but I simplified it a bit. 代码有点复杂,但是我简化了一点。 I know I could easily do this: 我知道我可以轻松做到这一点:

$svn_module s#.*/##;

And pull off just the end of the module. 然后拔出模块的末端。 But something strange is going on here: 但是,这里发生了一些奇怪的事情:

#! /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);

This prints: 打印:

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

However, I was expecting: 但是,我期望:

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

Why does my substitution expression remove trunk/ , but not the rest of the string up to trunk/ ? 为什么我的替换表达式删除了trunk/ ,但没有删除字符串的其余部分,直到trunk/呢?

By the way, adding an extra set of parentheses helps: 顺便说一句,添加额外的括号集将有助于:

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

will work. 将工作。

By the way, this is Perl 5.8.8. 顺便说一下,这是Perl 5.8.8。 This is a server, and pretty much the version I'm stuck on. 这是一台服务器,几乎是我坚持使用的版本。

Probably it should be this 大概应该是这个

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

Because, the other way it was a single alternation where the ^.* are not part 因为,相反,它是单个替换,其中^.*不存在
of the second alternation (the one that matched). 第二轮交替(匹配的轮换)。

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

Edit: Expanded new regex explained 编辑:扩展了新的正则表达式解释

 ^                       # 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

The equivalent in terms of your original regex is this 与您的原始正则表达式等效的是

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

I think you answered the question by yourself. 我想你自己回答了这个问题。 The | | operator has lowest precedence, so putting the additional parentheses is the solution. 运算符的优先级最低,因此可以添加括号。

Perhaps I'm missing something here, David, but instead of substituting everything up to the last part that you want to get what you want, why not capture just that last part? David,也许我在这里错过了一些东西,但是除了将所有内容替换为您想要的最后一部分之外,为什么不捕获最后一部分呢?

use strict;
use warnings;

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

Output: 输出:

SessionController

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM