RegEx - Java - 匹配字符串(012 | 123 | 234 | 345 | 456 | 567 | 678 | 789 | 890)

时间:2013-07-18 05:43:54

标签: java regex string passwords match

我正在进行密码增强,客户想要一个没有连续字母的密码,即:123,234。

我已经发现你可以在(012|123|234|345|456|567|678|789|890)之类的正则表达式中声明要匹配的字符串,并将其作为正则表达式序列。

该序列与其他序列分开以便于阅读。

问题是,即使我在密码字符中包含123或234,我也无法将密码与模式匹配。

我已经读过正则表达式无法检测123为连续数字,但作为字符串,它可以这样做吗?

2 个答案:

答案 0 :(得分:3)

如果您只处理要排除的这些数字字符串,则可以使用negative lookahead assertion来实现此目的:

^(?!.*(012|123|234|345|456|567|678|789|890))<regex>

其中<regex>是您用来匹配密码的实际正则表达式,而(?!...)是断言,它无法匹配正则表达式中的字符串。

如果您询问任何增加的字符序列,那么正则表达式不是正确的工具。你必须以编程方式做到这一点。

答案 1 :(得分:3)

如果您的字符序列有限,则可以在输入的匹配器上使用Pattern.find(),然后反转测试:

// Only the alternation is needed, no need for the capture
private static final Pattern PATTERN
    = Pattern.compile("012|123|234|345|456|567|678|789|890");

// ...

if (PATTERN.matcher(input).find())
    // fail: illegal sequence found

但是如果你想要检测到代码点彼此跟随,你必须使用字符函数:

final CharBuffer buf = CharBuffer.wrap(input);

int maxSuccessive = 0;
int successive = 0;
char prev = buf.get();
char next;

while (buf.hasRemaining()) {
    next = buf.get();
    if (next - prev == 1)
        successive++;
    else {
        maxSuccessive = Math.max(maxSuccessive, successive);
        successive = 0;
    }
    prev = next;
}

// test maxSuccessive

但请注意,这将根据“规范排序”测试连续的字符,而不是排序规则。例如,在某些区域设置中,a之后的内容是A,而不是b


更一般地说,如果你想测试密码要求和约束的发展,你最好稍微分解一下。例如,考虑一下:

public interface PasswordChecker
{
    boolean isValid(final String passwd);
}

为每个检查实现此接口(例如,长度,某些字符的存在/不存在等),当您检查密码时,请使用List个检查器;如果一个检查器返回false,则密码无效:

private final List<PasswordChecker> checkers = ...;

// then

for (final PasswordChecker checker: checkers)
    if (!checker.isValid(passwd))
        return false;
return true;

如果你使用番石榴,你可以忘记PasswordChecker并使用Predicate<String>