我有这样的文本;
2500.00 $120.00 4500 12.00 $23.00 50.0989
Iv写了一个正则表达式;
/(?!$)d+.d{2}/g
我希望它只匹配2500.00
,12.00
,而不是其他。
其要求是,它需要将"$"符号添加到小数点后正好有两位数字的数值上。对于当前的regex,它会在已经有"$"符号的regex上添加额外的"$"。它更长,但我只是简单地说一下。我知道我可以使用正则表达式删除"$",然后使用另一个正则表达式将"$"添加到所有需要的数字中。
任何帮助都将不胜感激,谢谢!
要回答您的问题,您需要在第一个数字所在的位置之前查看。
(?<!$)
但这不会起作用,因为它将匹配$123.45
的23.45
,将其更改为$1$23.45
,并且将匹配123.456
的123.45
,将其改为$123.456
。您需要确保在匹配之前或之后没有数字。
s/(?<![$d])(d+.d{2})(?!d)/$$1/g;
或者更快的
s/(?<![$d])(?=d+.d{2}(?!d))/$/g;
这很棘手,只是因为您试图在单个正则表达式中包含太多功能。如果您首先操作字符串来隔离每个数字,这将变得微不足道,正如这一行所示:
$ perl -F"(s+)" -lane's/^(?=d+.d{2}$)/$/ for @F; print @F;'
2500.00 $120.00 4500 12.00 $23.00 50.0989
$2500.00 $120.00 4500 $12.00 $23.00 50.0989
完整的代码如下:
while (<>) { # or whatever file handle or input you read from
my @line = split /(s+)/;
s/^(?=d+.d{2}$)/$/ for @line;
print @line; # or select your desired means of output
# my $out = join "", @line; # as string
}
请注意,这种拆分是非破坏性的,因为我们使用括号来捕获分隔符。因此,对于我们的示例输入,当使用Data::Dumper
:打印时,结果列表如下所示
$VAR1 = [
'2500.00',
' ',
'$120.00',
' ',
'4500',
' ',
'12.00',
' ',
'$23.00',
' ',
'50.0989'
];
这里的正则表达式只是两端锚定,允许包含数字,后面跟着一个句点.
和两个数字,而不包含其他数字。因为我们使用前瞻性断言,所以它会在开头插入美元符号,并保留其他所有内容。由于正则表达式的严格性,我们不需要担心检查任何其他字符,而且由于我们在空白处进行拆分,因此不需要检查任何此类字符。
您可以使用以下模式:
s/(?<!S)d+.d{2}(?!S)/$${^MATCH}/gp
或
s/(?<!S)(?=d+.d{2}(?!S))/$/g
我认为是较短的路。
(?<!S)
前面没有非白色字符的字符
(?!S)
后面没有不是白色字符的字符
这些双重否定的主要目的是自动包含字符串的开头和结尾。