我写了一个验证输入字符串的正则表达式。它必须至少有8个字符长度(由字母数字和标点字符组成),并且必须至少有一个数字和一个字母字符。所以我想出了正则表达式:
^(?=.*[0-9])(?=.*[a-zA-Z])[a-zA-Z0-9-,._;:]{8,}$
现在我必须用不支持前瞻的语言重写这个正则表达式,我应该如何重写那个正则表达式呢?
有效输入是:
1foo,bar
foo,bar1
1fooobar
foooobar1
fooo11bar
1234x567
a1234567
输入无效:
fooo,bar
1234-567
.1234567
答案 0 :(得分:7)
有两种方法。一种是组成一个处理所有可能替代方案的表达式:
^[a-zA-Z][0-9][a-zA-Z0-9-,._;:]{6,}$
|
^[a-zA-Z][a-zA-Z0-9-,._;:][0-9][a-zA-Z0-9-,._;:]{5,}$
|
^[a-zA-Z][a-zA-Z0-9-,._;:]{2}[0-9][a-zA-Z0-9-,._;:]{4,}$
等。这是一个组合的噩梦,但它会起作用。
更简单的方法是使用两个表达式两次验证相同的字符串:
^[a-zA-Z0-9-,._;:]{8,}$ # check length and permitted characters
和
<击> 撞击>
<击>[a-zA-Z].*[0-9]|[0-9].*[a-zA-Z] # check required characters
击> <击> 撞击>
编辑:@briandfoy正确指出分别搜索每个必需字符会更有效率:[a-zA-Z] # check for required alpha
和
[0-9] # check for required digit
答案 1 :(得分:2)
此问题原始标记为perl
,这就是我的答案。对于oracle的东西,我不知道你怎么做同样的事情。但是,我会尝试在它到目前为止验证这些东西。
我不会在一个正则表达式中这样做。当您决定更改规则时,您将获得相同数量的工作来制作新的正则表达式。即使它们可用,我也不会使用外观,因为我不想容忍所有的回溯。
这看起来像是很多代码,但解决问题的部分只是子程序。它有非常简单的模式。密码规则更改后,您可以添加或删除模式。使用study可能是值得的,但我没有调查:
use v5.10;
use strict;
use Test::More;
my @valids = qw(
1foo,bar
foo,bar1
1fooobar
foooobar1
fooo11bar
);
my @invalids = qw(
fooo,bar
short
nodigitbutlong
12345678
,,,,,,,,
);
sub is_good_password {
my( $password ) = @_;
state $rules = [
qr/\A[A-Z0-9,._;:-]{8,}\z/i,
qr/[0-9]/,
qr/[A-Z]/i,
];
foreach my $rule ( @$rules ) {
return 0 unless $password =~ $rule;
}
return 1;
}
foreach my $valid ( @valids ) {
ok( is_good_password( $valid ), "Password $valid is valid" );
}
foreach my $invalid ( @invalids ) {
ok( ! is_good_password( $invalid ), "Password $invalid is invalid" );
}
done_testing();
答案 2 :(得分:0)
我现在能想到的最好的是
(.*[a-zA-Z].*[0-9].*|.*[0-9].*[a-zA-Z].*)
但你必须分别检查字符串的长度。
答案 3 :(得分:0)
我会利用这些想法来获得最佳效果:
应该更快,但对于“0a000000000000000000”或“aaaaaaaaaaaaaaa”等输入,它会更慢(回溯):
regexp_like(regexp_substr(input_string, '^[a-zA-Z0-9_,.;:-]{8,}$'),
'[0-9].*[a-zA-Z]|[a-zA-Z].*[0-9]')
应该更快(不要错过第二行的[^ ...]):
(length(input_string) >= 8 and
not regexp_like(input_string, '[^a-zA-Z0-9_,.;:-]') and
regexp_like(input_string, '[a-zA-Z]') and
regexp_like(input_string, '[0-9]'))