【问题标题】:Backreferences to constituents of a group consisting of a fixed number of repetitions对包含固定重复次数的组的成分的反向引用
【发布时间】:2012-03-14 20:26:07
【问题描述】:

我想找到一个彼此重复 x 次的组,例如,由空格分隔的字母数字组合五次。我可以使用简单的重复语法,例如(?:\w\d ){5}

然后我想用其他东西替换这个 5x 字母数字中的空格。为此,我尝试通过在其周围放置括号来反向引用每个字母数字组合(没有空格):(?:(\w\d) ){5}。不幸的是,所有五个都存储在$1 中,即$1 每次匹配时都会被覆盖。

那么,有没有办法避免这种覆盖?或者有没有办法只替换子字符串中的东西?

编辑:

示例输入字符串:A1 A3 A4 B6 ::: A1 A3 A4 C5 B6

所需的输出字符串:A1 A3 A4 B6 ::: A1-A3-A4-C5-B6

也就是说,只有当有五个空格时才替换空格。在 Perl 中实现。

【问题讨论】:

  • 一些示例输入和输出,以及您使用的语言会有所帮助。

标签: regex perl backreference repeat


【解决方案1】:

它丑陋且不灵活,但是对于您的示例输入,如果它真的总是五个,并且如果您的示例输入永远不会改变,那么这应该可以工作:

s/(\w\d) +(\w\d) +(\w\d) +(\w\d) +(\w\d) */$1-$2-$3-$4-$5/

【讨论】:

  • 我就是从那里来的,对我来说主要问题是不灵活(我自然总是可以用 Perl 中的循环来解决)。
【解决方案2】:

如果你只是想解决问题,像这样的工作

$string = 'A1 A3 A4 B6 ::: A1 A3 A4 C5 B6';
$string =~ s/(\w\d(?: \w\d){4})/$_=$1; tr{ }{-}; $_/eg;
print "'$string'\n";

否则,Perl 中的组重复确实会覆盖每个循环的捕获缓冲区。

我不知道是否可以使用另一种编程方式。

编辑

如果您想覆盖字符之间的多个空格,请添加一个 + 量词和 tr///s - 挤压 tr/// 中的重复替换。
s/(\w\d(?: +\w\d){4})/$_=$1; tr{ }{-}s; $_/eg;

如果您有更高级的替换,您可以随时使用回调样式将正则表达式加倍
等价

$string =~ s/(\w\d(?: +\w\d){4})/fixspaces($1)/eg;
sub fixspaces {
   my $buf = shift;
   $buf =~ s/ +/-/g;
   $buf;
}

【讨论】:

  • 谢谢,这解决了我的问题。在 Perl 中可以在很多不太可能的位置(例如 $_=$1; tr{ }{-}s; $_ 通过 e 选项)降低表达式是非常有用的。
【解决方案3】:

这行得通:

#!usr/bin/perl
sub substitute{
    $substr=shift;
$substr=~s/\s/-/gi;
return $substr;
}

$test="hello a1 b2 c3 d4 e5 testing";
$test=~s/((?:\w\d\s){4})(\w\d)\s/&substitute($1).$2." "/egi;
print $test;

【讨论】:

  • (只需将量词更改为您想要的连字符组合数,如果您有 8 个序列,请将其更改为 7 等)
  • ...实际上与 Sin 发布的完全相同,nm
猜你喜欢
  • 1970-01-01
  • 2017-10-18
  • 1970-01-01
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
  • 2013-02-14
  • 1970-01-01
  • 2017-12-04
相关资源
最近更新 更多