我试图找到特定的模式并在其中进行替换。并将结果分配给另一个变量。
例如: 我有一个带有一些文本的变量$ 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”的结果。 所以,问题是:是否有可能在一次操作中做这样的事情?或者,最好的选择是什么,最小化代码?
答案 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