正则表达式:屏蔽除最后5位数之外的所有数字,忽略非数字

时间:2011-03-28 21:46:48

标签: regex

我想匹配一个包含17-23位数字的数字,其中插入空格或连字符,然后用星号替换除最后五位数之外的所有数字。我可以匹配以下正则表达式:

((?:(?:\d)([\s-]*)){12,18})(\d[\s-]*){5}

我的问题是我无法让正则表达式在第一部分中对[\s-]的所有实例进行分组,而我不知道如何用星号替换最初的12-18位数字({ {1}})。

4 个答案:

答案 0 :(得分:5)

这个怎么样:

s/\d(?=(?:[ -]*\d){5,22}(?![ -]*\d))/*/g

正向前瞻确保在刚好匹配的数字之前至少有5位数,而嵌入式否定前瞻确保不超过22位。

但是,在第一个匹配的数字之前,仍然可以有更多的数字。也就是说,如果有24位或更多位数,则此正则表达式仅对其中的最后23位进行操作。我不知道这对你来说是否有问题。

答案 1 :(得分:1)

即使假设单独使用正则表达式这是可行的,我敢打赌它会比使用你的正则表达式的非捕获版本慢,然后反复迭代匹配,只留下前5位并替换其余的他们用'*'。

答案 2 :(得分:1)

我认为你的正则表达式没问题,但你可能需要一个回调函数,你可以用另一个内联正则表达式插入星号。以下是Perl示例。

s/((?:\d[\s-]*){12,18})((?:\d[\s-]*){4}\d)/ add_asterisks($1,$2) /xeg

use strict;
use warnings;

my $str = 'sequence of digits 01-2  3-456-7-190 123-416 78 ';

if ($str =~ s/((?:\d[\s-]*){12,18})((?:\d[\s-]*){4}\d)/ add_asterisks($1,$2) /xeg )
{
   print "New string: '$str'\n";
}

sub add_asterisks {
   my ($pre,$post) = @_;
   $pre =~ s/\d/*/g;
   return $pre . $post;
}

__END__

输出

New string: 'sequence of digits **-* *-***-*-*** ***-416 78 '

答案 3 :(得分:0)

的答案提供 Alan Moore变体,并将所有字词[a-zA-Z0-9]用作\w而不是仅仅数字{ {1}}。 这也适用于任何长度的字符串。

\d

这个例子

public String maskNumber(String number){
    String regex = "\\w(?=(?:\\W*\\w){4,}(?!\\W*\\w))";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(number);
    while(m.find()){
        number = number.replaceFirst(m.group(),"*");
    }
    return number;
}

给出:

String[] numbers = {
        "F4546-6565-55654-5457",
        "F4546-6565-55654-54-D57",
        "F4546-6565-55654-54-D;5.7",
        "F4546-6565-55654-54-g5.37",
        "hd6g83g.duj7*ndjd.(njdhg75){7dh i8}",
        "####.####.####.675D-45",
        "****.****.****.675D-45",
        "**",
        "12"
};

for (String number : numbers){
    System.out.println(maskNumber(number));
}