我正在尝试构建ECMAScript(JavaScript)风味正则表达式,以根据以下条件测试密码的强度:
Characters Used Password Strength Length
ABC abc 123 #$& WEAK ...
1 x 1-5 ...
2 x 1-5
3 x 1-7
4 x 1-5
5 x x 1-4
6 x x 1-4
7 x x 1-4
8 x x 1-4
9 x x 1-4
10 x x 1-4
11 x x x 1-4
12 x x x 1-3
13 x x x 1-4
14 x x x 1-4
15 x x x x 1-3
因此,2
,ABCD
,0123456
,abCd
,aA#
等密码应标记为弱密码。指定组合012345678
,aA1#
等较长的密码不应该。
这是我很长的regex atm(基本上根据上表通过组粘合在一起):
/^(([A-Za-z&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,3})|([a-z0-9&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,4})|([A-Z0-9&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,4})|([a-zA-Z0-9]{1,4})|([a-z]{1,5})|([A-Z]{1,5})|([0-9]{1,7})|([&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,5}))$/
匹配行(在表上方):12
/([A-Za-z&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,3})/
匹配行:14、9
/([a-z0-9&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,4})/
匹配行:13、10、7
/([A-Z0-9&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,4})/
匹配行:11、8、6、5
/([a-zA-Z0-9]{1,4})/
匹配行:2
/([a-z]{1,5})/
匹配行:1
/([A-Z]{1,5})/
匹配行:3
/([0-9]{1,7})/
匹配行:4
/([&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,5})/
是否可以重用我在[]
[&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]
中指定的特殊字符,因此不必在每个组中都写所有特殊字符?
答案 0 :(得分:2)
有没有一种方法可以重用我在[] ...中指定的特殊字符,因此我不必在每个组中都写所有特殊字符?
不带正则表达式文字,不。
不过,您可以使用RegExp
构造函数来实现。您可以使用String.raw
来减轻它想要一个字符串的事实,因此您不必担心转义反斜杠:
const chars = String.raw`[the chars]`;
const rex = new RegExp(String.raw`^...${chars}...${chars}...$`);
您可以通过为此创建一个特定的标记函数来进一步实现此功能(这是我新书第10章的示例;有关详细信息,请参见我的个人资料):
const createRegex = (template, ...values) => {
// Build the source from the raw text segments and values
const source = String.raw(template, ...values);
// Check it's in /expr/flags form
const match = /^\/(.+)\/([a-z]*)$/.exec(source);
if (!match) {
throw new Error("Invalid regular expression");
}
// Get the expression and flags, create
const [, expr, flags = ""] = match;
return new RegExp(expr, flags);
};
然后:
const chars = String.raw`[the chars]`;
const rex = createRegex`/^...${chars}...${chars}...$/`;
答案 1 :(得分:0)
我不确定您使用的是哪个正则表达式引擎。但是,如果是Perl或Ruby,则可以使用子例程在很大程度上实现这一目标。子例程是正则表达式中的重复模式。
您可能知道反向引用。但是,子例程与反向引用不同。在反向引用的情况下,捕获组的内容是匹配的,而不是模式。但是,对于子例程,将重复模式匹配。
让我们举个例子。
abcd-defg
/(?<dd>[a-z]+)-\g<dd>/
。比赛将会成功。\g<dd>
部分是Ruby中名为dd
的组的子例程调用。 (\g<group_name>
是Ruby regex样式。对于您使用的引擎,它可能有所不同。)更多详细信息在这里:
就您而言,我认为您可以为每个组在正则表达式中首次出现时命名,然后将其称为子例程。例如,让我们打电话
[A-Z]
为A
[a-z]
为a
[0-9]
为n
s
(不确定我是否正确使用此模式。)然后,用于12的模式 /([A-Za-z&*@\^}\]\\):,$=!><–{[(%+#;\/~_?.]{1,3})/
变为
/((\g<A>|\g<a>|\g<s>)){1,3})/
即A OR a OR s repeated 1-3 times
。
并且 11、8、6、5 的模式变为/([a-zA-Z0-9]{1,4})/
/((\g<a>|\g<A>|\g<n>)){1,4})/
即a OR A OR n repeated 1-4 times
。