Возможно, вы сможете смешивать и сопоставлять регулярное выражение и код -
$line =~ /(?{($cnt,@ary)=(0,)})^(?:([^,]+)(?{push @ary,$cnt; push @ary,$^N})|,(?{$cnt++}))+/x
and print join( ',', @ary);
расширен -
$line =~ /
(?{($cnt,@ary)=(0,)})
^(?:
([^,]+) (?{push @ary,$cnt; push @ary,$^N})
| , (?{$cnt++})
)+
/x
and print join( ',', @ary);
некоторые тесты
С небольшим изменением flesk и sln (ищите fleskNew и slnNew),
победителем становится fleskNew при удалении оператора подстановки.
code -
use Benchmark qw( cmpthese ) ;
$samp = "x,,10.3,,q,,5.2,3.1,,,ghy,g,,l,p";
$line = $samp;
cmpthese( -5, {
flesk1 => sub{
$index = 0;
join ",",
map {join ",", @$_}
grep $_->[1],
map {[$index++, $_]}
split ",", $line;
},
flesk2 => sub{
($i, @vars) = (0,);
while ($line =~ s/^(,*)([^,]+)//) {
push @vars, $i += length($1), $2;
}
$line = $samp;
},
fleskNew => sub{
($i, @vars) = (0,);
while ($line =~ /(,*)([^,]+)/g) {
push @vars, $i += length($1), $2;
}
},
sln1 => sub{
$line =~ /
(?{($cnt,@ary)=(0,)})
^(?:
([^,]+) (?{push @ary,$cnt; push @ary,$^N})
| , (?{$cnt++})
)+
/x
},
slnNew => sub{
$line =~ /
(?{($cnt,@ary)=(0,)})
(?:
(,*) (?{$cnt += length($^N)})
([^,]+) (?{push @ary, $cnt,$^N})
)+
/x
},
} );
числа -
Rate flesk1 sln1 flesk2 slnNew fleskNew
flesk1 20325/s -- -51% -52% -56% -60%
sln1 41312/s 103% -- -1% -10% -19%
flesk2 41916/s 106% 1% -- -9% -17%
slnNew 45978/s 126% 11% 10% -- -9%
fleskNew 50792/s 150% 23% 21% 10% --
некоторые тесты 2
Добавляет встроенную замену и обрезку Birei (все в одном)решение.
Аббревиатуры:
Flesk1 изменен для удаления окончательного «соединения», поскольку он не включен в
других решений регулярных выражений.Это дает ему шанс лучше на скамейке.
Бирей отклоняется на скамейке, поскольку это изменяет исходную строку, чтобы быть окончательным решением.
Этот аспект не может быть удален.Разница между Birei1 и BireiNew заключается в том, что новый
удаляет последний ','.
Flesk2, Birei1 и BireiNew имеют дополнительные накладные расходы на восстановление исходной строки
из-за оператора подстановки.
Победитель по-прежнему выглядит как FleskNew ..
code-
use Benchmark qw( cmpthese ) ;
$samp = "x,,10.3,,q,,5.2,3.1,,,ghy,g,,l,p";
$line = $samp;
cmpthese( -5, {
flesk1a => sub{
$index = 0;
map {join ",", @$_}
grep $_->[1],
map {[$index++, $_]}
split ",", $line;
},
flesk2 => sub{
($i, @vars) = (0,);
while ($line =~ s/^(,*)([^,]+)//) {
push @vars, $i += length($1), $2;
}
$line = $samp;
},
fleskNew => sub{
($i, @vars) = (0,);
while ($line =~ /(,*)([^,]+)/g) {
push @vars, $i += length($1), $2;
}
},
sln1 => sub{
$line =~ /
(?{($cnt,@ary)=(0,)})
^(?:
([^,]+) (?{push @ary,$cnt; push @ary,$^N})
| , (?{$cnt++})
)+
/x
},
slnNew => sub{
$line =~ /
(?{($cnt,@ary)=(0,)})
(?:
(,*) (?{$cnt += length($^N)})
([^,]+) (?{push @ary, $cnt,$^N})
)+
/x
},
Birei1 => sub{
$i = -1;
$line =~
s/
(?(?=,+)
( (?: , (?{ ++$i }) )+ )
| (?<no_comma> [^,]+ ,? ) (?{ ++$i })
)
/
defined $+{no_comma} ? $i . qq[,] . $+{no_comma} : qq[]
/xge;
$line = $samp;
},
BireiNew => sub{
$i = 0;
$line =~
s/
(?: , (?{++$i}) )*
(?<data> [^,]* )
(?: ,*$ )?
(?= (?<trailing_comma> ,?) )
/
length $+{data} ? "$i,$+{data}$+{trailing_comma}" : ""
/xeg;
$line = $samp;
},
} );
результаты -
Rate BireiNew Birei1 flesk1a flesk2 sln1 slnNew fleskNew
BireiNew 6030/s -- -18% -74% -85% -86% -87% -88%
Birei1 7389/s 23% -- -68% -82% -82% -84% -85%
flesk1a 22931/s 280% 210% -- -44% -45% -51% -54%
flesk2 40933/s 579% 454% 79% -- -2% -13% -17%
sln1 41752/s 592% 465% 82% 2% -- -11% -16%
slnNew 47088/s 681% 537% 105% 15% 13% -- -5%
fleskNew 49563/s 722% 571% 116% 21% 19% 5% --