匹配模式和替换

时间:2013-11-04 05:31:00

标签: regex perl

我正在尝试使用格式为“h hours,mm minutes,ss seconds”替换我的xml文件中标记内的h:mm:ss格式。我面临的问题是,如果时间标记以一行开头和结尾,则正则表达式可以替换。当标签开始和结束于第二行时,我无法替换格式。

这是我正在尝试的 -

while(<$rd>) {
   my $currLine = $_;
   $_ =~ s/\<time\> *(.):(..):(..) *\<\/time>/$1 hours, $2 minutes, $3 seconds/g;
   print FILE $_;
}

我的输入文件如下所示 -

<time> 1:04:55    </time> this is a good time <time> 
2:04:22 </time> to ask your question Alfred, 
but did you check time <time> 3:45:32 </time> and <time> 02:03:45 </time>

我可以将格式“h:mm:ss”替换为“h hours,mm minutes,ss seconds”,而不是2:04:22,因为标签打开并以不同的行结束。

2 个答案:

答案 0 :(得分:4)

不是逐行阅读,而是阅读</time>,并允许除''之外的其他空格:

{
    use autodie 'open';
    open my $input, '<', 'input.xml';
    open my $output, '>', 'output.xml';
    local $/ = '</time>';
    while (<$input>) {
        s/<time>\s*(.):(..):(..)\s*<\/time>/$1 hours, $2 minutes, $3 seconds/;
        print $output $_;
    }
}

答案 1 :(得分:0)

您不需要多行正则表达式功能吗?这是我尝试过的代码片段

my $str = '<time> 1:04:55    </time> this is a good time <time>
2:04:22 </time> to ask your question Alfred,
but did you check time <time> 3:45:32 </time> and <time> 02:03:45 </time>';

$str =~ /<time>[\n\s]*(\d):(\d\d):(\d\d)[\n\s]*<\/time>/mg;
print $1, "\n";
print $2, "\n";
print $3, "\n";

输出

1
04
55

此处/m告诉正则表达式引擎将$str视为多行字符串。使用g将在字符串中的所有位置应用更改。

我没有写出你需要的确切解决方案,而只是多线正则表达式的工作方式。如果您需要更多帮助,请告诉我。

修改

我认为在这个关于多行正则表达式的问题中值得注意。

 my $str = '<time> 1:04:55    </time> this is a good time <time>
     2:04:22 </time> to ask your question Alfred,
     but did you check time <time> 3:45:32 </time> and <time> 02:03:45 </time>';

$str =~ s/<time>[\n\s]*(\d?\d):(\d\d):(\d\d)[\n\s]*<\/time>/$1 hours, $2 minutes, $3 seconds/mg;
print $str;

输出

1 hours, 04 minutes, 55 seconds this is a good time 2 hours, 04 minutes, 22 seconds to ask your question Alfred,
but did you check time 3 hours, 45 minutes, 32 seconds and 02 hours, 03 minutes, 45 seconds

问题是你的完整输入应该是你正在应用正则表达式的字符串。