否定地向前看整数,但前面有一个字符(perl)



我有这样的文本;

2500.00 $120.00 4500  12.00 $23.00 50.0989

Iv写了一个正则表达式;

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

我希望它只匹配2500.0012.00,而不是其他。

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

任何帮助都将不胜感激,谢谢!

要回答您的问题,您需要在第一个数字所在的位置之前查看

(?<!$)

但这不会起作用,因为它将匹配$123.4523.45,将其更改为$1$23.45,并且将匹配123.456123.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)后面没有不是白色字符的字符

这些双重否定的主要目的是自动包含字符串的开头和结尾。

相关内容

最新更新