如何创建动态正则表达式生成器?技术实现咨询
密码正则表达式生成器实现修正
需求说明
实现一个接收密码策略配置对象的函数,根据配置生成对应的正则表达式,用于验证密码是否符合复杂度要求。
原尝试代码
function generateRegexExpression(policy) { let pattern = ""; if (policy.UppercaseLength > 0) pattern += `A-Z{${policy.UppercaseLength},}`; if (policy.LowercaseLength > 0) pattern += `a-z{${policy.LowercaseLength},}`; if (policy.NonAlphaLength > 0) pattern += `[!@#$%^&*()_+-={}\\[\\]\\|;:'\",.<>/?\`~]{${policy.NonAlphaLength},}`; if (policy.NumericLength > 0) pattern += `\\d{${policy.NumericLength},}`; if (policy.AlphaLength > 0) pattern += `[A-Za-z]{${policy.AlphaLength},}`; pattern = `^[${pattern}]{${policy.MinimumLength},${policy.MaximumLength}}$`; return new RegExp(pattern); } const policy = { "MinimumLength": 8, "MaximumLength": 20, "UppercaseLength": 0, "LowercaseLength": 0, "NonAlphaLength": 0, "NumericLength": 1, "AlphaLength": 1 }; const PolicyRules = [ "请选择长度在8到20字符之间的新密码。", "必须包含至少1个字母。", "必须包含至少1个数字。", "新密码不得与用户名或上一次使用的密码相同。", "请选择与最近5次使用过的密码不同的密码。", "请勿与任何人共享您的密码。" ];
原代码问题点
- 字符类语法错误:直接拼接
A-Z会被解析为单个字符(A、-、Z),而非大写字母范围,正确写法应为[A-Z] - 逻辑设计错误:将所有规则塞进一个大字符类
[],导致正则仅能匹配单一类型字符的重复,无法满足“同时包含字母、数字”这类多条件组合要求 - 缺失强制约束逻辑:未使用正向预查实现“至少包含N个某类字符”的强制校验,无法达到策略要求的复杂度约束
修正后的代码
function generateRegexExpression(policy) { const lookaheads = []; // 至少N个大写字母 if (policy.UppercaseLength > 0) { lookaheads.push(`(?=(.*[A-Z]){${policy.UppercaseLength},})`); } // 至少N个小写字母 if (policy.LowercaseLength > 0) { lookaheads.push(`(?=(.*[a-z]){${policy.LowercaseLength},})`); } // 至少N个非字母符号(优化转义,将-放在字符类末尾避免范围歧义) if (policy.NonAlphaLength > 0) { lookaheads.push(`(?=(.*[!@#$%^&*()_+={}\\[\\]\\|;:'",.<>/?\`~-]){${policy.NonAlphaLength},})`); } // 至少N个数字 if (policy.NumericLength > 0) { lookaheads.push(`(?=(.*\\d){${policy.NumericLength},})`); } // 至少N个字母(大小写均可) if (policy.AlphaLength > 0) { lookaheads.push(`(?=(.*[A-Za-z]){${policy.AlphaLength},})`); } // 基础长度限制,允许所有符合规则的字符组合 const lengthPattern = `^.{${policy.MinimumLength},${policy.MaximumLength}}$`; // 拼接预查规则与长度规则 const fullPattern = lookaheads.join('') + lengthPattern; return new RegExp(fullPattern); } // 测试策略生成的正则 const policy = { "MinimumLength": 8, "MaximumLength": 20, "UppercaseLength": 0, "LowercaseLength": 0, "NonAlphaLength": 0, "NumericLength": 1, "AlphaLength": 1 }; const passwordRegex = generateRegexExpression(policy); console.log(passwordRegex.test("abc12345")); // true(符合长度,含字母和数字) console.log(passwordRegex.test("12345678")); // false(无字母) console.log(passwordRegex.test("abcdefgh")); // false(无数字)
密码策略规则
- 请选择长度在8到20字符之间的新密码。
- 必须包含至少1个字母。
- 必须包含至少1个数字。
- 新密码不得与用户名或上一次使用的密码相同。
- 请选择与最近5次使用过的密码不同的密码。
- 请勿与任何人共享您的密码。
内容的提问来源于stack exchange,提问作者Priyanka Chaurasia
相关产品推荐
相关产品推荐

