使用JS regexp检查某些字符是否在字符串中

时间:2011-09-02 16:11:19

标签: javascript regex

我正在研究用于生成密码字符串的JS函数,它为a-z小写,A-Z大写,0-9和标点符号采用四个参数。我整理了一个基本字符串,如下所示:

function genpwd(azlc,azuc,num,pun,len) {
    var chars = "";
    if (azlc) chars += "abcdefghijklmnopqrstuvwxyz";
    if (azuc) chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    if (num)  chars += "012345678901234567890123";
    if (pun)  chars += "!@#%&()=?+-_.:,;*{}[]^$/";

然后我循环遍历基本字符串(给定密码长度)并随机挑出一个新字符串并将其作为输出密码返回。

    for(i=0;i<len;i++) {
        nextChar = chars.charAt(Math.floor(Math.random()*charsN));
        password += nextChar;
    }
    return password;
}

这是生成随机字符串的一种非常简单的方法,但它不能保证每个“char group”中至少有一个char实际包含在输出字符串中。

我已经看了一些关于如何使用regexp的其他示例,但无法弄清楚如何修改它们以我想要的方式工作。我认为解决这个问题的“最简单”的方法可能就是使用正则表达式 - 就像这样:

if (password.magic_regexp_stuff) {
    return password;
} else {
    password = genpwd(azlc,azuc,num,pun,len);
}
  1. 我是在正确的轨道上吗?
  2. 任何人都可以帮助我使用正则表达式吗?

  3. 更新:

    好的,所以经过你们所有人的宝贵意见后,我最终得到了这个功能。

    我也从mVChr的建议(感谢man!)切换到Py发布的那个,所以我很确定NobRuked指出的“统计问题”(没有任何其他的话)不会不再是一个问题。有人可以确认一下吗? :)

    我还必须修改函数的参数和方法来处理要使用的字符集。有关改进的任何建议吗?

    function passwd(len, azlc, azuc, num, pun) {
        var len = parseInt(len),
            ar = [],
            checker = [],
            passwd = '',
            good = true,
            num, num2,
            sets = 0;
        if(!len || len < 4) len = 12;
        if(!azlc && !azuc && !num && !pun) { azlc = 1; azuc = 1; num = 1; pun = 1; }    
    
        if (azlc) {
            ar.push("abcdefghijklmnopqrstuvwxyz");
            checker.push(0);
            sets++;
        }
        if (azuc) {
            ar.push("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
            checker.push(0);
            sets++;
        }
        if (num) {
            ar.push("0123456789");
            checker.push(0);
            sets++;
        }
        if (pun) {
            ar.push("!@#%&()=?+-_.:,;*{}[]^$/");
            checker.push(0);
            sets++;
        }
        for (var i=0;i<len;i++){
            num=rand(0,sets);
            num2=rand(0,ar[num].length);
            passwd+=ar[num][num2];
            checker[num]=1;
        }
        for (var i=0;i<sets;i++){
            if(checker[i]===0)
                good=false;
        }
        if (good){
            return passwd;
        }
        else{
            return passwd(len);
        }
    }
    

    非常感谢大家的帮助,非常感谢!

6 个答案:

答案 0 :(得分:4)

我认为正则表达式不适合这项工作。您的尝试理论上可以永远循环(尽管极不可能),因为无法保证生成的密码与正则表达式匹配。

我想确保包含每个组中的一个字符的简单方法是明确地包含它。因此,假设您的密码长度至少为4个字符,我建议使用以下伪代码:

chars = charFrom(azlc) + charFrom(azuc) + charFrom(num) + charFrom(pun)
do the following, length_of_password - 4 times:
    chars += charFrom(azlc + azuc + num + pun)
chars = shuffle(chars)

charFrom()shuffle()的实施留给了读者。

答案 1 :(得分:2)

要使用正则表达式执行此操作,您实际上只需要(最多)四个正则表达式:

function genpwd(azlc,azuc,num,pun,len) {
    var chars = "", regexs = [],

    testRegexs = function(pw) {
        var ii;
        for (ii = 0; ii < regexs.length; ii += 1) {
            if (!regexs[ii].test(pw)) {
                return false;
            }
            return true;
        }
    };

    if (azlc) { 
        chars += "abcdefghijklmnopqrstuvwxyz"; 
        regexs.push(/[a-z]/); 
    }
    if (azuc) { 
        chars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; 
        regexs.push(/[A-Z]/); 
    }
    if (num) { 
        chars += "012345678901234567890123"; 
        regexs.push(/0-9/); 
    }
    if (pun) { 
        chars += "!@#%&()=?+-_.:,;*{}[]^$/"; 
        regexs.push(/[\!\@\#\%\&\(\)\=\?\+\-\_\.\:\,\;\*\{\}\[\]\^\$\/]/); 
    }

    do
    {
        // Generate a password...
    }
    while (!testRegexs(password));

    return password;
}

答案 2 :(得分:1)

我会接受另一个approch。

我有4个字符串

lower = "abcdefghijklmnopqrstuvwxyz";
upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
num = "0123456789";
other = "!@#%&()=?+-_.:,;*{}[]^$/";

然后要生成密码,我将取0到3之间的随机整数,然后是0和选择字符串之间的另一个整数来取一个字符。

要检查是否已采取所有措施,我只需检查第一个随机选择中是否已采用4整数。

代码看起来像

function psswd(len){
    var ar=[lower,upper,num,other],
        checker=[0,0,0,0],
        passwd="",
        good=true,
        num,num2;
    for (var i=0;i<len;i++){
        num=randomInt(0,3);
        num2=randomInt(0,ar[num].length);
        passwd+=ar[num][num2];
        checker[num]=1;
    }
    for (var i=0;i<3;i++){
        if(checker[i]===0)
            good=false;
    }
    if (good){
        return passwd;
    }
    else{
        return psswd(len);
    }
}

可能不是最佳,但不需要正则表达式。

答案 3 :(得分:1)

function genpwd(azlc,azuc,num,pun,len) {
  var sets = [], 
      pw = [],
      i, j, t;
  if (azlc) sets.push("abcdefghijklmnopqrstuvwxyz");
  if (azuc) sets.push("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  if (num)  sets.push("0123456789");
  if (pun)  sets.push("!@#%&()=?+-_.:,;*{}[]^$/");
  while (len) {
   pw.push(sets[len%sets.length][~~(Math.random()*sets[len%sets.length].length)]);
   len--;
  }
  i = pw.length;
  while (--i) {
    j = ~~(Math.random()*(i+1));
    t = pw[j];
    pw[j] = pw[i];
    pw[i] = t;
  }
  return pw.join('');
}

编辑:添加了随机播放

答案 4 :(得分:0)

仅供记录,验证可以在一个正则表达式中完成:

/^(?=.*[A-Z])(?=.*[a-z])(?=.*\d)(?=.*[!@#%&()=?+_.:,;*{}\[\]^$\/-])/.test(mypassword)

关于密码生成方案,请参阅this

答案 5 :(得分:0)

这是我的函数的最终版本(我还用一些信息更新了问题帖子)。

再次感谢大家的帮助! :)

/**
 * Generate Password
 * ---
 * Generates a random text string containing characters types according to given 
 * parameters. Uses all character types by default. Output string length will at 
 * minimum be the number of character types currently in use.
 *
 * @param   int     Output string lenght
 * @param   bool    Use letters a-z lower case
 * @param   bool    Use letters A-Z upper case
 * @param   bool    Use numbers 0-9
 * @param   bool    Use punctuations (!@#$?*...)
 * @return  string  Generated password string
 */

function genPwd(l,w,x,y,z){
    var a=[],c=[],p='',g=true,n1,n2,s=0,i=0;
    if(!w&&!x&&!y&&!z){w=1,x=1,y=1,z=1;}
    if(w){c.push(0);s++;a.push("abcdefghijklmnopqrstuvwxyz");}
    if(x){c.push(0);s++;a.push("ABCDEFGHIJKLMNOPQRSTUVWXYZ");}
    if(y){c.push(0);s++;a.push("012345678901234567890123456789");}
    if(z){c.push(0);s++;a.push("!@#%&/(){}[]=?+*^~-_.:,;");}
    if(l<s){l=s;}for(i=0;i<l;i++){n1=Math.floor(Math.random()*(s-0));
    n2=Math.floor(Math.random()*(a[n1].length-0));p+=a[n1][n2];c[n1]=1;}
    for(i=0;i<s;i++){if(c[i]===0)g=false;}
    if(g){return p;}else{return genPwd(l,w,x,y,z);}
}