我写了这个验证方法但是遇到了问题。
function validate_password(pwd)
{
var score = 0;
// Min length is 8
if (pwd.length<8)
return false;
// Is lower present?
if (/[a-z]/g.test(pwd))
{
console.log('a-z test on "'+pwd+'":' + /[a-z]+/g.test(pwd));
score++;
}
// Is upper present?
if (/[A-Z]/g.test(pwd))
{
console.log('A-Z test on: "'+pwd+'":' + /[A-Z]+/g.test(pwd));
score++;
}
// Is digit present?
if (/\d/g.test(pwd))
{
console.log('digit test on: "'+pwd+'":' + /\d/g.test(pwd));
score++;
}
// Is special char present?
if (/\W/g.test(pwd))
{
console.log('spec char test on: "'+pwd+'":' + /\W/g.test(pwd));
score++;
}
if (score>=3)
return true;
else
return false;
}
这是写入控制台的内容:
>>> validate_password('aaasdfF#3s')
a-z test on "aaasdfF#3s":true
A-Z test on: "aaasdfF#3s":true
digit test on: "aaasdfF#3s":true
spec char test on: "aaasdfF#3s":true
true
>>> validate_password('aaasdfF#3s')
a-z test on "aaasdfF#3s":true
false
在第一次尝试时,它似乎按预期工作,但是当我第二次调用该方法时,它无法按预期工作。
所以,我的问题是为什么第一次尝试和第二次尝试的结果之间存在差异?
谢谢! :)
答案 0 :(得分:1)
请参阅test
上的MDC文档。
当您想知道是否在字符串中找到模式时,请使用test方法(类似于String.search方法);有关更多信息(但执行速度较慢),请使用exec方法(类似于String.match方法)。与exec一样,在同一个正则表达式实例上多次调用的测试将超过上一个匹配。
解决方案是从正则表达式中删除全局或g
标记:
/[a-z]/
代替/[a-z]/g
,依此类推。
考虑这个simple example,看看问题存在的原因:
var l = /[a-z]/g;
// initial search starts at the beginning, matches "a" and returns true
l.test("a"); // true
// since the first character matched, lastIndex moves to the next index - 1
l.lastIndex; // 1
// this time we pass a different string to the regex, but unfortunatly it
// starts searching from the lastIndex which is 1. There are no lower case
// letters from this point onwards (only "---"), so return value is false.
l.test("x---"); // false
// Since this search failed, lastIndex wraps around to the beginning, so the
// next search will work as expected
l.lastIndex; // 0
对于您的给定输入"aaasdfF#3s"
,小写[a-z]
测试将成功7次,因为有7个小写字符,但是第8次失败。并且从第9次到第15次再次成功,依此类推。其他测试将在每个备用时间失败,因为每种类型的角色中只有一个 - "F"
,"#"
和"3"
,并且它在lastIndex
处包围0时测试失败。
问题似乎源于这样一个事实:状态在函数调用之间保留在那些RegExp对象中,这意味着RegExp对象只创建一次,而不是每次调用该函数。这个小test证实了这一点:
function RegExpStatePersistenceTest() {
var regex = /[a-z]/g;
regex.counter = regex.counter || 0;
regex.counter++;
console.log("counter:" + regex.counter);
}
RegExpStatePersistenceTest(); // counter: 1
RegExpStatePersistenceTest(); // counter: 2
RegExpStatePersistenceTest(); // counter: 3
RegExpStatePersistenceTest(); // counter: 4
如果使用new RegExp(..)
显式创建了一个新对象,那么在每次调用该函数时,都会创建一个全新的RegExp对象,并且不会在调用之间保留状态。
另见why-regexp-with-global-flag-in-javascript-give-wrong-results