缩短JavaScript正则表达式条件

3
我有以下JavaScript函数,它在输入框内按键弹起时运行:
var passwordInput = document.getElementsByName("newPassword")[0].value;

var upperCase= new RegExp('[A-Z]');
var lowerCase= new RegExp('[a-z]');
var numbers = new RegExp('[0-9]');

if ( passwordInput.match(lowerCase) ) {
    $('.strength-check__rule[data-index="1"]').addClass('check-rule--pass');
} else {
    $('.strength-check__rule[data-index="1"]').removeClass('check-rule--pass');
}

if (passwordInput.match(upperCase)) {
    $('.strength-check__rule[data-index="2"]').addClass('check-rule--pass');
} else {
    $('.strength-check__rule[data-index="2"]').removeClass('check-rule--pass');
}

if(passwordInput.match(numbers)) {
    $('.strength-check__rule[data-index="3"]').addClass('check-rule--pass');
} else {
    $('.strength-check__rule[data-index="3"]').removeClass('check-rule--pass');
}

if(passwordInput.length >= 8) {
    $('.strength-check__rule[data-index="4"]').addClass('check-rule--pass');
} else {
    $('.strength-check__rule[data-index="4"]').removeClass('check-rule--pass');
}

每个条件语句中的addClasses仅是给li添加一个类,以显示已经满足该条件。我想知道是否有任何提示可以缩短或使其更加简洁,特别是前三个非常相似的条件。


如果它不依赖于[data-index="#"],你可以将其全部压缩成这个^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.{8}),但看起来你正在跟踪各自的强度。 - user557597
@sln 是的,这就是我在想的,似乎这样会更简洁。只是不太确定具体该怎么做。想提供一个漂亮的勾来作为示例 :) - JordanBarber
@Oli:就我个人而言,我区分开发人员(能够编写算法的人)和API用户。对于这样一项如此基础的任务,真的需要使用模块/第三方库吗? - Casimir et Hippolyte
@CasimiretHippolyte 同意了 - JordanBarber
@CasimiretHippolyte 嗯,你知道的,你并没有改善你的情况 :-) - Oli
显示剩余9条评论
4个回答

1
也许这可以帮助节省一些代码行和字符:
var passwordInput = document.getElementsByName("newPassword")[0].value;

var upperCase= new RegExp('[A-Z]');
var lowerCase= new RegExp('[a-z]');
var numbers = new RegExp('[0-9]');

var x = [0,0,0,0];

x[0] = passwordInput.match(lowerCase) ? 1 : 0;
x[1] = passwordInput.match(upperCase) ? 1 : 0;
x[2] = passwordInput.match(numbers) ? 1 : 0;
x[3] = passwordInput.length > 7 ? 1 : 0;

for (var i = 0; i < 4; i++) {
    if (x[i] == 1) {
        $('.strength-check__rule[data-index="' + (i+1) + '"]').addClass('check-rule--pass');
    } else {
        $('.strength-check__rule[data-index="' + (i+1) + '"]').removeClass('check-rule--pass');
    }
}

1
怀疑它无法再缩短了:

var passwordInput = $('[name=newPassword]').val();
var tests = {
  1:/[a-z]/.test(passwordInput),
  2:/[A-Z]/.test(passwordInput),
  3:/[0-9]/.test(passwordInput),
  4:passwordInput.length >= 8
};
for(var i=1; i<=4; i++)
  $('.strength-check__rule[data-index=' +i+ ']')
  [ tests[i] ? 'addClass' : 'removeClass' ]('check-rule--pass');

使用对象的想法不错,我认为 for (var i in tests) 更合适。 - Washington Guedes
就关系而言,属性迭代似乎更合适,但这样会包括继承的属性,没有 hasOwnProperty。假设它没有扩展和首次扩展它一样糟糕,因为如果稍后包含了扩展对象以获取所需功能,那么它可能会在以后出现故障。IE 在其中有自己的问题。如果您愿意,请称呼我为“落伍”,但经过 17 年的 JavaScript 后,我尽可能多地提供支持。 - Ultimater
我明白你的意思,但是...使用对象而不是数组有什么优势呢? - Washington Guedes
两个优点:一是因为数组从索引0开始,我们只关心1到4的索引。当然,我们可以使用i+1,但这会影响可读性。第二个优点是它使每个键与其测试的关联更加清晰。如果在某个时候需要添加另一个测试,则不会丢失关联,因为通过为每个测试指定特定的键,您明确表明了键很重要。 - Ultimater

0
我猜你可以使用 switch .attr() 来改变类,类似于:

$("#pass").keyup(function(e) {
var pass = $("#pass").val();
switch (true) {
  case /((?=.*[a-z])(?=.*[A-Z])(?=.*[\d])(?=.{8,})[^ ]*)/.test(pass):
    $("#stenght").attr("class", 'green');
    break;
  case /((?=.*[a-z])(?=.*[A-Z])(?=.*[\d])[^ ]*)/.test(pass): 
    $("#stenght").attr("class",'blue');
    break;
  case /((?=.*[a-z])(?=.*[A-Z])[^ ]*)/.test(pass):
    $("#stenght").attr("class", 'orange');
    break;
  case /((?=.*[a-z])[^ ]*)/.test(pass):
    $("#stenght").attr("class",'red');
    break;
}
  });
.red{color:red;} .orange{color:orange;} .blue{color:blue;} .green{color:green;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="pass" type="text"><br>
<span class="red" id="stenght">PASSWORD STENGHT<span>


0
根据您的脚本,我进行了重构并得到了不同的结果。它可以进一步优化,但是基本思路是您有一个函数来评估密码强度,并从该值中操作强度计。
<input type="text" name="newPassword" onkeyup="validate();">

<ul class="strength">
    <li class="strength-1">*</li>
    <li class="strength-2">*</li>
    <li class="strength-3">*</li>
    <li class="strength-4">*</li>
</ul>

<script type="text/javascript">

    $('ul.strength').css('list-style-type', 'none').find('li').css('float', 'left').hide();

    function getPasswordStrength(password) {
        var strength = 0;
        if(password.match(/[A-Z]/)) { strength++; }
        if(password.match(/[a-z]/)) { strength++; }
        if(password.match(/[0-9]/)) { strength++; }
        if(password.length > 8) { strength++; }
        return strength;
    }

    function validate() {
        var strength = getPasswordStrength(document.getElementsByName("newPassword")[0].value);

        $('ul.strength').find('li').hide();
        for(var  i = 1; i < strength + 1; i++) {
             $('li.strength-' + i).show();
        }
    }
</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接