【问题标题】:How to replace all occurrences of X between Y's?如何替换 Y 之间所有出现的 X?
【发布时间】:2011-10-21 01:22:58
【问题描述】:

我不确定这个问题是否可以用正则表达式(Perl5 语法)解决,但这里是一个不言自明的例子:

smth Y1 test X foo X Y2 bar X Y1 X X Y2
s/?/Z/g
smth Y1 test Z foo Z Y2 bar X Y1 Z Z Y2

考虑 Y1 总是有一个匹配的 Y2 并且没有重叠。

【问题讨论】:

  • 在这种情况下必须发生什么? YXYXY
  • 在我的数据集中不可能有嵌套或不匹配的 Y
  • 如果你的 Y 是 XML 标签,你会想要使用 XML 解析器,因为 XML 基本上不能用正则表达式解析。
  • @glenn,我明白了。但我认为,在某些(罕见的)情况下,值得使用正则表达式进行简单的转换,您可以将其编写为只需要运行一次的简单单行。
  • 不,为此使用 xlst(开个玩笑)

标签: python regex perl sed


【解决方案1】:

给你:

$str = 'smth Y1 test X foo X Y2 bar X Y1 X X Y2';
$str =~ s/X(?=((?!Y1).)*Y2)/Z/g;
print $str; #smth Y1 test Z foo Z Y2 bar X Y1 Z Z Y2

【讨论】:

  • [^(Y1)] 没有做你认为的事情
  • @ysth,请您进一步解释一下吗?
  • @Andrew [^(Y2)] 表示不是(Y1,也不是)
【解决方案2】:

有点尴尬,但是:

my $string = 'smth Y1 test X foo X Y2 bar X Y1 X X Y2';
$string =~ s/(Y1.*?Y2)/ (my $tmp = "$1") =~ tr!X!Z!; $tmp /ge;
print $string;

【讨论】:

    【解决方案3】:

    我的解释性解决方案(在 Perl 中):

    $sample = 'smth Y1 test X foo X Y2 bar X Y1 X X Y2';
    $sample =~ s/(?<=Y1) ((?:(?!Y1|Y2).)+) (?=Y2)/subX($1)/xeg;
    
    sub subX {
      ($str) = @_;
      $str =~ s/X/Z/g;
      return $str;
    }
    
    print $sample;
    

    输出:

    smth Y1 test Z foo Z Y2 bar X Y1 Z Z Y2

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-07
      • 2021-09-17
      相关资源
      最近更新 更多