Perl正则表达式 - 用#替换字符串中的所有数字,除非它们具有某个前缀

时间:2014-03-30 10:30:38

标签: regex perl negative-lookbehind

我试图用'#'替换字符串中的所有数字,前提是它们没有特定的前缀。 这些数字可能会显示为单词的一部分,也可能单独显示为单词。

例如,使用ABC作为前缀,这是期望的结果。

输入:

sdkfjsd 12312981 sdkfjsdfhbnmawd 1298 ,smdfsdnfk2342423 
sdlkfsdfs 20349 ABC1203912 2034234aac <-- ABC<number> stays, the other numbers do not
ABC1203912

结果(请注意,第2,3行的ABC带有数字):

sdkfjsd # sdkfjsdfhbnmawd # ,smdfsdnfk#
sdlkfsdfs # ABC1203912 #aac <-- ABC<number> stays, the other numbers do not
ABC1203912

我试着用正面背面的负面看法来做这件事:s/(?<!ABC)\d+/#/g。 在这种情况下,只有ABC之后的第一个数字不会被替换,其余的将会被替换。

我的下一步是将字符串拆分为包含ABC\d+的部分,并对其他部分执行简单替换。

如果不分成多个字符串,将会欣赏如何完成整个事情的任何建议。

谢谢!

编辑1:将aac移回正确的位置。 编辑2:我使用perl 5.8.5,以防这是相关的。由于与我无法控制的代码的兼容性问题,我无法更新到更新的版本。

3 个答案:

答案 0 :(得分:3)

我不明白你的意思&#34;我的下一步是将字符串拆分为包含ABC\d+的部分,然后对其他部分执行简单替换。&#34 ;,但看起来这不是你的主要问题。请让我知道。

要匹配前面没有关键字ABC的每个数字,那么您可以使用此正则表达式:

(?<!ABC|\d)\d+

如果数字前面有ABC或其他数字(从而阻止\d+匹配,如果从数字中间开始,则会阻止匹配。

regex101 demo

请注意,您的问题中有两部分字符串移动了。我只接受您使用的输入。


如果上述方法不起作用(例如,正则表达式引擎表示后视图中的图案不能是可变宽度,或沿着这些线条的某些东西),那么替代等价物是:

(?<!ABC)(?<!\d)\d+

regex101 demo

答案 1 :(得分:1)

它并不完全清楚你想要什么,尤其是因为2034234aac字段在你的例子中被奇怪地修改过。

但是,对你自己的负面观察的这种修改可能会有用。请注意,它保留了以ABC开头的完整任何序列,例如ABCX1234。目前尚不清楚这是否是正确的行为。

use strict;
use warnings;

my $s = <<'__END_TEXT__';
sdkfjsd 12312981 sdkfjsdfhbnmawd 1298 ,smdfsdnfk2342423 
sdlkfsdfs 20349 ABC1203912 2034234aac <-- ABC<number> stays, the other numbers do not
ABC1203912
__END_TEXT__

$s =~ s/\b(?!ABC)[a-z]*\K\d+/#/gi;

print $s;

或者,对于早于10的Perl 5版本,请使用此

$s =~ s/\b((?!ABC)[a-z]*)\d+/$1#/gi;

<强>输出

sdkfjsd # sdkfjsdfhbnmawd # ,smdfsdnfk# 
sdlkfsdfs # ABC1203912 #aac <-- ABC<number> stays, the other numbers do not
ABC#

答案 2 :(得分:0)

你需要使用“零宽度负向后观断言”:只有在没有紧接的情况下才会匹配。

EG。匹配不在ABC之前的数字:

(?<!ABC)\d

你已经有了这个,但下一步是匹配前缀和多个数字:

(?<!ABC)\d+

没有直接帮助,因为你需要不匹配。

稍微改一下这个问题:

  

替换不在前缀后面的数字和一个或多个数字

IE中。在“ABC123”中你不想替换1,2或3.我们可以将零宽度负向后看断言扩展为包括数字:

(?<!ABC\d+)\d

因此也排除了前缀后面的数字。

NB 这假设Perl支持可变宽度的lookbehinds:肯定是正则表达式的第一个扩展,包括它们必须固定宽度的lookbehinds,但它已经有一段时间了我认真使用Perl正则表达式,所以我假设P​​erl正则表达式实现已经扩展到与其他平台相匹配。

编辑:哎呀,s /正面/负面/外观。