Regex 匹配模式并替换

Regex 匹配模式并替换,regex,perl,Regex,Perl,我试图用格式“h小时,mm分钟,ss秒”替换xml文件中标记中的h:mm:ss格式。我面临的问题是,如果时间标记以一行开始和结束,那么正则表达式很适合替换。当标记在第二行开始和结束时,我无法替换格式 这就是我正在尝试的- while(<$rd>) { my $currLine = $_; $_ =~ s/\<time\> *(.):(..):(..) *\<\/time>/$1 hours, $2 minutes, $3 seconds/g;

我试图用格式“h小时,mm分钟,ss秒”替换xml文件中标记中的h:mm:ss格式。我面临的问题是,如果时间标记以一行开始和结束,那么正则表达式很适合替换。当标记在第二行开始和结束时,我无法替换格式

这就是我正在尝试的-

while(<$rd>) {
   my $currLine = $_;
   $_ =~ s/\<time\> *(.):(..):(..) *\<\/time>/$1 hours, $2 minutes, $3 seconds/g;
   print FILE $_;
}
while(){
我的$currLine=$\;
$\\*(..):(..)*\/$1小时,$2分钟,$3秒/g;
打印文件$;
}
我的输入文件如下所示-

<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>
1:04:55这是个好时机
2:04:22问你的问题Alfred,
但是你查过时间3:45:32和02:03:45了吗

我可以将格式“h:mm:ss”替换为“h小时,mm分钟,ss秒”,但不能替换为2:04:22,因为标记在不同的行打开和结束。

不是逐行读取,而是最多读取一个
,并允许除“”以外的其他空格:

{
    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 $_;
    }
}
{
使用autodie“打开”;
打开我的$input,,'output.xml';
本地$/='';
而(){
s/\s*(.):(…)\s*/$1小时,$2分钟,$3秒/;
打印$output$;
}
}

不要逐行读取,而是最多读取一个
,并允许除“”以外的其他空格:

{
    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 $_;
    }
}
{
使用autodie“打开”;
打开我的$input,,'output.xml';
本地$/='';
而(){
s/\s*(.):(…)\s*/$1小时,$2分钟,$3秒/;
打印$output$;
}
}

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

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";

这里代码>/M告诉ReGEX引擎将“代码> $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;

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

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

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";

这里代码>/M告诉ReGEX引擎将“代码> $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;

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

您是否在while循环中使用正则表达式行?这种方法要求您读取字符串中的整个输入,然后对其应用正则表达式。更改将应用于整个字符串。然而,在您的情况下,最好采用ysth提到的方法。但是,我将在我的答案中添加一个更具体的示例,这样就不会有人感到困惑了。您是否在while循环中使用了regex行?这种方法要求您读取字符串中的整个输入,然后对其应用正则表达式。更改将应用于整个字符串。然而,在您的情况下,最好采用ysth提到的方法。然而,我将在我的答案中添加一个更具体的例子,这样就不会有其他人感到困惑。