【问题标题】:perl string to array with repetition operatorperl 字符串到带有重复运算符的数组
【发布时间】:2012-10-09 12:12:30
【问题描述】:

我有一个字符串,比如:“5 3*3 4*1 6*3 14*4 3*2 2*3 4”

我希望这个字符串变成一个包含元素的数组:

@array = ( "5", "3" x 3, "1" x 4, "3" x 6, "4" x 14, "2" x 3, "3" x 2, "4" );

我猜还有比这更好(更短)的方法:

$string = "5 3*3 4*1 6*3 14*4 3*2 2*3 4";
@array = split (/\s+/,$string);
foreach(@array) {
   if ( /\*/ ) {
      s/^(\d+)\*(\d+)/"$2" x $1/g;
   } else {
      print "$_\n";
      $_ = '"'. $_ .'"';
   }
}

编辑:这段代码实际上做了我在原始问题中所说的应该做的事情。但这实际上不是我想要的。我希望最终的数组看起来像:

@array = (5, 3, 3, 3, ...)

【问题讨论】:

  • 你想要(5, 3, 3, 3...)吗?还是保持原来的字符串不变?
  • 是的,感谢您的澄清。我才意识到模棱两可。我想要你猜到的:(5, 3, 3, 3, ...)
  • 我现在很困惑,我的代码是否符合您的要求?听起来您想使用重复运算符

标签: perl search replace repeat


【解决方案1】:

算法:

  1. 取出字符串并在空格处分割
  2. 如果 /(\d+)*(\d+)/ 正则表达式匹配一个元素,我们会重复列表元素。否则,我们将元素不变地传递。

实现(单行)

perl -MData::Dumper -E'$string = "5 3*3 4*1 6*3 14*4 3*2 2*3 4"; @array = map{/(\d+)\*(\d+)/ ? ($2)x$1 : $_} split /\s+/, $string; say Dumper \@array'

实施(正常)

my $string = "5 3*3 4*1 6*3 14*4 3*2 2*3 4";
my @array = map {/(\d+)\*(\d+)/ ? ($2)x$1 : $_} split /\s+/, $string;
# do something with @array:
say "@array";

请注意,字符串上使用的重复运算符会重复并连接字符串:

"a"x3 ~~ "aaa"

但是用在列表上,它会返回一个包含重复元素的列表:

[(1)x3] ~~ [1,1,1]
[(1,2)x2] ~~ [1,2,1,2]

【讨论】:

  • 谢谢。这就是诀窍。我修改了 map 函数(阅读 perldoc perlop 等),但仍然没有完全掌握它。你有像我一样为 The Simple 描述它的好资源吗?
  • @MarkWayne map 函数在perlfunc page 中进行了解释。它获取右侧的列表,对其执行操作,然后将结果填充到左侧的列表中。在我的代码中,我使用了它可以输出任意数量的新列表元素这一事实。
【解决方案2】:

在空格上进行字符串替换和拆分。

use strict;
use Data::Dumper;

my $string = "5 3*3 4*1 6*3 14*4 3*2 2*3 4";
$string =~ s/\*/x/g;
my @list = split(' ', $string );
warn Dumper( \@list );

【讨论】:

  • 谢谢。不,这不是正确的想法。数字必须按顺序颠倒,重复次数与“*”前的数字相对应。
【解决方案3】:

您的 if 块中缺少您的 print 语句,但这是另一种选择:

$string = "5 3*3 4*1 6*3 14*4 3*2 2*3 4";
$string =~ s/\s+/#/g;                     # change space delimiter to something else
$string =~ s/(?<!\*)(\d+)(?!\*)/"$1"/g;   # quote nums that don't have an asterisk next to it
$string =~ s/(\d+)\*(\d+)/"$2" x $1/g;    # make all changes at once
@array = split (/#/,$string);             # split the string

不过,我认为您的方法更清晰;这很重要。

【讨论】:

    猜你喜欢
    • 2013-02-16
    • 2021-08-11
    • 1970-01-01
    • 2016-02-02
    • 1970-01-01
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 2013-08-04
    相关资源
    最近更新 更多