【问题标题】:Perl conditional substitutionPerl 条件替换
【发布时间】:2023-03-24 06:16:01
【问题描述】:

我有一个路径名,其中包含我想替换的占位符:

# an example path with a placeholder
my $path = '%myproject%Web/ui/images/';

# mapping of all placeholders   
my %placeholders = (
  myproject => 'myproject/installation/all'
);

# substituting all placeholders in the path
$path =~ s!%(.*?)%!/$placeholders{$1}/!g;

# works fine -> 'myproject/installation/all/Web/ui/images/'
print $path; 

这段代码运行良好,但有一个问题:我有一长串文件名和指定的不同占位符(因此是哈希)。现在,为了更加稳健,如果路径中指定的占位符在 %placeholders 映射中不存在,我想抛出一个错误。

有没有办法做到这一点?

【问题讨论】:

    标签: regex perl substitution


    【解决方案1】:

    现在为了更加稳健,如果路径中指定的占位符在 %placeholders 映射中不存在,我想抛出一个错误

    这可以使用/e 轻松完成:

    $path =~ s{%([^%]+)%}{
       exists($path{$1})
          ? '/'.$path{$1}.'/'
          : die "Placeholder $1 does not exist"
    }ge;
    

    注意:我认为最好将.*? 替换为[^%]+ 以防止不正确的匹配。

    【讨论】:

    • 在这个用例中,对定义的简单测试可能就足够了,因为在字符串中包含现有但未定义的值是错误的。这会将替换代码简化为$path{$1} // die ...
    • @amon 对已定义的测试,不存在。但是,是的,我认为这是可能的。但他没有说他的 Perl 版本是什么,因为// 是相对较新的运算符。
    • @amon 感谢你们出色而快速的回复。 amons 版本适用于我的 perl 5.12。但是有一个问题:我有/$path{$1}/ / 也需要在那里。
    • @Christoph 为此解决了问题,// 运算符似乎不可能
    • 当然,使用三元运算符很容易,但不能使用定义运算符?我更喜欢它,因为它紧凑。
    【解决方案2】:

    使用given 可以做到这一点,但它比given 的语句修饰符形式可用时要长得多。

    use v5.10;;
    use warnings;
    
    my $path = '%myproject%Web/ui/images/'; 
    
    my %placeholders = (
      myproject => 'myproject/installation/all'
    );
    
    $path =~ s!%(\w+)%!given ($placeholders{$1} // die qq(Invalid placeholder "$1")) { "/$_/" }!ge;
    
    print $path;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-15
      • 2017-11-11
      • 1970-01-01
      • 2010-10-30
      • 2023-04-09
      相关资源
      最近更新 更多