如何在Perl中替换字符串中的一个或多个字符串
问题描述:
$ args [0]是对包含一次或多次的字符串的引用。我每次移动的时间是可变的秒数,但是我需要找到一种方法将更改的时间存储(替换)回原始字符串。任何帮助表示赞赏。这里大概是我的工作:如何在Perl中替换字符串中的一个或多个字符串
my $TIMEREGEX = qr/(\d{2}:\d{2}:\d{2}\.\d{3}|\d{2}:\d{2}:\d{2})/x;
if (my @sTime = ${$args[0]} =~ /$TIMEREGEX/g)
{
warn "\ttime(s) found @sTime\n" if $main::opt{d};
for my $i (0..$#sTime)
{
$sTime[$i] =~ /(\d{2}):(\d{2}):(\d{2})(\.(\d{3}))?/;
my $epoch_time = ($1 * 3600) + ($2 * 60) + $3;
$epoch_time += $epoch_shift;
my @f;
$f[0] = $epoch_time % 86400/3600; # hours
$f[1] = $epoch_time % 3600/60; # minutes
$f[2] = $epoch_time % 60; # seconds
my $save = $sTime[$i];
$sTime[$i] = sprintf ("%02d:%02d:%02d", $f[0], $f[1], $f[2]);
$sTime[$i] .= $4 if defined ($4);
warn "\tTimeShift $save => $sTime[$i]\n" if $main::opt{d};
### some other stuff
}
# ${$args[0]} = "$1$t[0]$4$t[1]$7$t[2]$10";
### save the changes to ${$args[0]} !
}
答
use 5.010; # or better for 'say' and '//'
use strictures;
use Time::Piece qw();
my @args; my $epoch_shift = 500;
${$args[0]} = 'foo18:00:00.123bar18:00:00baz18:00:00quux';
${$args[0]} =~
s{
(\d{2}:\d{2}:\d{2}) # capture hh:mm:ss
(\.\d{3})? # optionally capture
# decimal dot and milliseconds
}
{
(
$epoch_shift
+ Time::Piece->strptime($1, '%T')
)->strftime('%T').($2 // '')
}egx;
say ${$args[0]};
# foo18:08:20.123bar18:08:20baz18:08:20quux
+0
谢谢!我没有想到在替换中使用表达式 – harmonic 2012-04-28 14:14:51
也许你在寻找's ///'?还可以用'e'键使用'/// e'。 – gaussblurinc 2012-04-23 10:57:01
或期待'split'函数和'join'函数。他们会让你的工作变得更简单;) – gaussblurinc 2012-04-23 10:58:24
为什么不使用可以为你处理时间的模块?像[DateTime](http://search.cpan.org/perldoc?DateTime)或[Time :: Piece](http://search.cpan.org/perldoc?Time::Piece)。 – TLP 2012-04-23 10:59:04