负面向前看整数但前面有一个字符(perl)

时间:2013-12-06 14:36:14

标签: regex perl

我有这样的文字;

2500.00 $120.00 4500  12.00 $23.00 50.0989

我写了一个正则表达式;

/(?!$)\d+\.\d{2}/g

我希望它只匹配2500.0012.00没有别的。

要求是它需要将'$'符号添加到小数点后正好两位数的数值上。使用当前的正则表达式,它会向已经有'$'符号的广告提供额外的'$'。它更长,但我只是简单地说。我知道我可以使用正则表达式删除'$'然后使用另一个正则表达式将'$'添加到所有想要的数字。

任何帮助将不胜感激!

3 个答案:

答案 0 :(得分:3)

要回答你的问题,你需要先看 第一个数字所在的位置。

(?<!\$)

但这不起作用,因为它会与23.45的{​​{1}}相匹配,将其更改为$123.45,并且会与$1$23.45的{​​{1}}匹配将其更改为123.45。您希望确保在匹配之前或之后没有数字。

123.456

或者更快

$123.456

答案 1 :(得分:1)

这很棘手,因为您试图在单个正则表达式中包含太多功能。如果你首先操纵字符串以隔离每个数字,这就变得微不足道了,正如这个单线程所示:

$ 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'
        ];

我们的正则表达式只是固定在两端,并允许包含数字,后跟一个句点.和两个数字,没有别的。因为我们使用先行断言,它会在开头插入美元符号,并保留其他所有内容。由于我们的正则表达式的严格性,我们不需要担心检查任何其他字符,并且因为我们在空格上分割,我们不需要检查任何这样的字符。

答案 2 :(得分:0)

您可以使用此模式:

s/(?<!\S)\d+\.\d{2}(?!\S)/\$${^MATCH}/gp

s/(?<!\S)(?=\d+\.\d{2}(?!\S))/\$/g

我认为这是较短的方式。

(?<!\S)前面没有非白色字符的字符

(?!\S)后面跟不是白色字符的字符

这些双重否定的主要好处是你自动包括字符串案例的开始和结束。