我想匹配一个包含17-23位数字的数字,其中插入空格或连字符,然后用星号替换除最后五位数之外的所有数字。我可以匹配以下正则表达式:
((?:(?:\d)([\s-]*)){12,18})(\d[\s-]*){5}
我的问题是我无法让正则表达式在第一部分中对[\s-]
的所有实例进行分组,而我不知道如何用星号替换最初的12-18位数字({ {1}})。
答案 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)
为java的答案提供regex 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));
}