首页 > 解决方案 > Perl 中带有条件替换的正则表达式替换

问题描述

我的 Perl 技能非常初级,我正在尝试使用正则表达式替换(除其他外)将加载在标量变量中的数据文件中的日期转换为四位数年份。

我有以下工作要为所有年份增加 20 年。

$data00 =~ s/^D(\d{2})\/(\d{2})\/(\d{2})\n/D$1\/$2\/20$3\n/gm;

但是,这些日期包括 2000 年之前的日期。

在寻找解决方案时,我遇到了 /e 选项,该选项表示它将替换评估为 Perl 代码。但是我没有在我遇到的所有文档中找到它,我不确定语法是什么。

有没有办法评估 $3 匹配并输出 20 如果 $3 小于 50 来制造 2000 和 19 如果不是,制造 1997?我选择 50 是因为它似乎是一个安全的中间地带。

出于说明目的,尽管我知道这是不正确的:

$data00 =~ s/^D(\d{2})\/(\d{2})\/(\d{2})\n/D$1\/$2\/(if($3<50)20 else 19)$3\n/eg;

/e 在这种情况下是否合适?

从巨大的文本文件中提取的行示例。

D04/07/97
D04/14/98
D10/06/99
D10/13/05
D03/04/10
D12/09/10
D01/20/11
D12/22/11

标签: regexperl

解决方案


When using /e, the replacement expression must be a valid Perl expression (i.e. what you could put following $x =).

You can use the conditional operator (?:) to evaluate an expression differently based on a condition:

s/^D(\d{2})\/(\d{2})\/(\d{2})\n/ "D$1\/$2\/".( $3 < 50 ? 20 : 19 )."$3\n" /eg

Note that replacing the delimiter can make things far more readable when many / are involved.

s{^D(\d{2})/(\d{2})/(\d{2})\n}{ "D$1/$2/".( $3 < 50 ? 20 : 19 )."$3\n" }eg

推荐阅读