【问题标题】:java RE class - lookahead (implementing password validator)java RE 类 - 前瞻(实现密码验证器)
【发布时间】:2016-08-26 09:20:12
【问题描述】:

我正在尝试使用正则表达式来验证给定密码是否包含: 1. 大写字符 2.小​​写字符 3. 一个号码 4. 至少8个字符

我找到了以下正则表达式来定义此类约束:

RE r = new RE("^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d$@$!%*#?&]{8,}$");

不幸的是,我仅限于使用 java 的 org.apache.regexp.RE 类的遗留系统。

无需前瞻,我能够将规则 1-3 定义为以下正则表达式:

RE r = new RE("^(((.*([A-Z]+).*([0-9]+).*|.*([0-9]+).*([A-Z]+)).*)$)")

但我不知道如何在不使用“?=”元字符的情况下将长度参数添加到此字符串。

尝试编译“(?=...)”失败并出现以下错误:

org.apache.regexp.RESyntaxException: Syntax error: Missing operand to closure
    at org.apache.regexp.RECompiler.syntaxError(Unknown Source)
    at org.apache.regexp.RECompiler.terminal(Unknown Source)
    at org.apache.regexp.RECompiler.closure(Unknown Source)
    at org.apache.regexp.RECompiler.branch(Unknown Source)
    at org.apache.regexp.RECompiler.expr(Unknown Source)
    at org.apache.regexp.RECompiler.terminal(Unknown Source)
    at org.apache.regexp.RECompiler.closure(Unknown Source)
    at org.apache.regexp.RECompiler.branch(Unknown Source)
    at org.apache.regexp.RECompiler.expr(Unknown Source)
    at org.apache.regexp.RECompiler.compile(Unknown Source)
    at org.apache.regexp.RE.<init>(Unknown Source)
    at org.apache.regexp.RE.<init>(Unknown Source)
    at com.idit.hscx.passwordTest.testPassword(passwordTest.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.internal.runners.JUnit38ClassRunner.run(JUnit38ClassRunner.java:84)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)

我的问题: RE 类中是否存在“前瞻”? 如果没有,我如何在 RE 类正则表达式中实现“AND”运算符?

谢谢!

【问题讨论】:

  • 如果限制太多,使用简单检查这些字符是否存在
  • 只需使用两个正则表达式。没有理由只需要一个
  • 两个问题:Q1 如果您使用具有固定数量字符(如^(?=.{0,8}[a-z])^(?=.?.?.?.?.?.?.?.?[a-z]) 而不是无限的.*?)的前瞻,会发生什么情况。 Q2 如果您使用 (?&lt;=[a-z].{0,8})$(?&lt;=[a-z].?.?.?.?.?.?.?.?)$ 之类的后视,会发生什么情况。我问是因为 java 真的不喜欢无限的外观。

标签: java regex apache


【解决方案1】:

您列出的第二个表达式仅测试 4 个条件中的 2 个。它只查找大写字母和数字。

我可以想到几种方法来做到这一点。

首先,有六种不同的大写、小写和数字组合。

  • ULN
  • UNL
  • LUN
  • LNU
  • NLU
  • NUL

A计划

使用两个正则表达式。第一个表达式将验证字符串中至少有一个字符类型。它有点长,因为它会查找六种组合中的每一种。

^.*?(?:[A-Z]+.*?[a-z]+.*?[0-9]|[A-Z]+.*?[0-9]+.*?[a-z]|[a-z]+.*?[A-Z]+.*?[0-9]|[a-z]+.*?[0-9]+.*?[A-Z]|[0-9]+.*?[a-z]+.*?[A-Z]|[0-9]+.*?[A-Z]+.*?[a-z])

第二个测试可以是正则表达式或字符串长度测试。正则表达式看起来像:

^.{8,}

B计划

将构建一个更复杂的正则表达式来测试每个位置的大写、小写和数字的所有不同组合。这个正则表达式自然会很大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-25
    • 2018-11-27
    • 2023-03-31
    • 2012-12-25
    • 1970-01-01
    相关资源
    最近更新 更多