【问题标题】:perl regex to replace $ with $$ unless $ followed by one of ^ @ ( $perl 正则表达式用 $$ 替换 $ 除非 $ 后跟 ^ @ ( $
【发布时间】:2022-11-15 13:03:29
【问题描述】:

我想用 $$ 替换 $ 字符,除非 $ 后跟 ^@($ 之一。

例如给出:

$(bar) $@ $$.z $^.zh $(foo) $foo $bar 

我想要:

$(bar) $@ $$.z $^.zh $(foo) $$foo $$bar

我有一个残酷的 hack 方法来做到这一点(用一个临时的可能是唯一的垃圾序列替换我不想修改的模式),替换剩下的所有东西,然后撤消我的临时模式。

my $var = ' $(bar) $@ $$.z $^.zh $(foo) $foo $bar ';
                                                                                        
my $d = '$';
my $at = '@';                                                                               
   
$var =~ s/\$\(/<<<<DDDDBBBB>>>>/g;
$var =~ s/\$\@/<<<<DDDDAAAA>>>>/g;
$var =~ s/\$\^/<<<<DDDDCCCC>>>>/g;            
$var =~ s/\$\$/<<<<DDDDDDDD>>>>/g;
$var =~ s/\$/$d$d/g;                   
$var =~ s/<<<<DDDDBBBB>>>>/$d(/g;
$var =~ s/<<<<DDDDAAAA>>>>/$d$at/g;                                
$var =~ s/<<<<DDDDCCCC>>>>/$d^/g;
$var =~ s/<<<<DDDDDDDD>>>>/$d$d/g;
                                                                                                                                                            
print "$var\n";   

这有效,但它很难看。我天真的一次班轮尝试是:

my $var = ' $(bar) $@ $$.z $^.zh $(foo) $foo $bar ';
print "$var\n";
my $d = '$';
$var =~ s/\$([^\@\(\$\^])/$d$d$1/g;
print "$var\n";

但这不能正确处理 $$。 $$ 的第一个匹配项无法按需要替换,但是“$.” “$$”的一部分。字符序列被替换,给出:

$(bar) $@ $$$.z $^.zh $(foo) $$foo $$bar 

我可以做一个混合体:

my $var = ' $(bar) $@ $$.z $^.zh $(foo) $foo $bar ';

my $d = '$';
my $at = '@';

print "$var\n";

$var =~ s/\$\$/<<<<DDDDDDDD>>>>/g;
$var =~ s/\$([^\@\(\^])/$d$d$1/g;
$var =~ s/<<<<DDDDDDDD>>>>/$d$d/g;

print "$var\n";

但这仍然很丑陋,只是没那么糟糕。有没有办法用一个 perl 正则表达式来做这个替换,也许使用断言或环视?

【问题讨论】:

    标签: regex perl


    【解决方案1】:

    负前瞻的经典用法

    use warnings;
    use strict;
    use feature 'say';
    
    my $str = shift // q($(bar) $@ $$.z $^.zh $(foo) $foo $bar); 
    
    my $re = '[' . join( '', map { quotemeta } qw{^ @ ( $} ) . ']';
    
    $str =~ s{$(?! $re )}{$$}xg;
    
    say $str;
    

    【讨论】:

    • 不会产生所需的输出。
    【解决方案2】:

    我想用 $$ 替换 $ 字符,除非 $ 后跟 ^、@、( 或 $ 之一。

    展望未来。

    s/ $ (?! [^@($] ) / '$$' /xeg
    

    但这不能正确处理 $$。

    它按照你说的你想要的去做。

    但是您似乎想忽略 $ 字符,如果它前面的 $ 字符数是奇数。

    一个简单的处理方法是简单地替换$$$,而不是^/@/)

    s/ $ (?: $ | (?! [^@(] ) ) / '$$' /xeg
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-28
      • 2013-09-27
      • 2018-10-20
      相关资源
      最近更新 更多