Perl的。同时匹配和替换

时间:2014-03-07 11:00:16

标签: perl matching substitution simultaneous

我试图找到特定的模式并在其中进行替换。并将结果分配给另一个变量。

例如: 我有一个带有一些文本的变量$ text,其中我试图找到类似“Date:\ s + \ d {4}。\ d \ d。\ d \ d”的模式,在其中替换破折号的点,然后将结果分配给$结果。

此版本有效:

($result) = $text =~ /Date:\s+(\d{4}\.\d\d\.\d\d)/igs;
 $result =~ s/\./-/g;

但我试图在一次手术中做到这一点。类似的东西:

($result) = $text =~ s/Date:\s+(\d{4})\.(\d\d)\.(\d\d)/$1-$2-$3/igs;

但它给了我“1”的结果。 所以,问题是:是否有可能在一次操作中做这样的事情?或者,最好的选择是什么,最小化代码?

4 个答案:

答案 0 :(得分:1)

my $result;
$text =~ s/Date:\s+(\d{4})\.(\d\d)\.(\d\d)/ $result= "$1-$2-$3" /ei;

答案 1 :(得分:0)

如果您移动括号以便$text首次分配到$result,则您可以将替换应用于$result而不是$text,因此您可以删除您不想要的所有多余文本,并使用您用密码-代替点构建日期的原始想法:

(my $result = $text) =~ s/.*Date:\s+(\d{4})\.(\d\d)\.(\d\d).*/$1-$2-$3/igs;

请注意在字符串的开头和结尾使用.*,这将消耗所有文本,因此唯一剩下的就是日期。这行代码实际上是两个操作,如下所示:

my $result = $text;
$result =~ s/..../;

另一个版本是使用后脚本for循环,它将利用$_别名列表参数的事实:

tr/./-/ for ((my $result) = $text =~ /Date:\s+([\d.]+)/);

这会将日期分配给$result,然后将$result传递给for中的参数列表,并将音译应用于$result。它影响实变量$_,因为$result =~ tr/./-/; 在循环中有别名。

另请注意,在我看来,这确实是一个学术问题。我不建议在生产代码中使用它,而且您的原始版本更好,更易读。虽然我会使用音译而不是替换:

{{1}}

答案 2 :(得分:0)

请试试这个 ($ result = $ text)=〜s / Date:\ s +(\ d {4})。(\ d \ d)。(\ d \ d)/ $ 1- $ 2- $ 3 / igs

答案 3 :(得分:0)

您不应过于热衷于将多个操作写入单个语句:它只会破坏代码的可读性。但我建议你写这样的东西。

在原始模式匹配中使用/s修饰符毫无意义,因为它仅影响.元字符,并且模式中没有这些修饰符。此外,使用/g是没有意义的,因为您只对一场比赛感兴趣。

不要试图将两个语句连接成一行,因为if语句修饰符也适用于my声明,它具有一些非常奇怪的效果。

use strict;
use warnings;
use 5.010;

my $text = 'Date: 1994.04.04';

my $result;
$result = $1 =~ tr/./-/r if $text =~ /Date:\s+(\d{4}\.\d\d\.\d\d)/i;

say $text;
say $result;

<强>输出

Date: 1994.04.04
1994-04-04