REGEX - 输入必须有x个唯一数字

时间:2017-03-23 15:08:35

标签: javascript regex

我想知道是否有人知道正则表达式检测到使用了最少x位的方法。

例如,如果我输入一个6位数的111222,但我的正则表达式中必须至少有3个唯一数字,这将导致有效的失败。

但是如果我有123456会通过,因为使用了超过三个唯一数字。

有点像(显然它不会像下面那样。)

/^[0-9]{6}*3$/

非正则表达方式



var telcstart = $('#num').val(),
  telc1 = (telcstart.match(/1/g) || []).length,
  telc2 = (telcstart.match(/2/g) || []).length,
  telc3 = (telcstart.match(/3/g) || []).length,
  telc4 = (telcstart.match(/4/g) || []).length,
  telc5 = (telcstart.match(/5/g) || []).length,
  telc6 = (telcstart.match(/6/g) || []).length,
  telc7 = (telcstart.match(/7/g) || []).length,
  telc8 = (telcstart.match(/8/g) || []).length,
  telc9 = (telcstart.match(/9/g) || []).length,
  telc0 = (telcstart.match(/0/g) || []).length,
  totaltelc = "a:" + telc1 + " b:" + telc2 + " c:" + telc3 + " d:" + telc4 + "e:" + telc5 + " f:" + telc6 + " g:" + telc7 + " h:" + telc8 + " i:" + telc9 + " j:" + telc0,
  finaltelc = (totaltelc.match(/0/g) || []).length;

if (finaltelc <= 8) {
  alert('passed');
} else {
  alert('failed');
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="number" id="num" value="123451212111">
&#13;
&#13;
&#13;

4 个答案:

答案 0 :(得分:2)

^(?=.*(.)(?!$|.*\1))(?=.*(?!\1)(.)(?!$|.*\2))[0-9]+$

&#13;
&#13;
function check(value) {
  var res = document.getElementById('result');
  if (/^(?=.*(.)(?!$|.*\1))(?=.*(?!\1)(.)(?!$|.*\2))[0-9]+$/.test(value)) {
    res.innerText = '✓ OK';
  } else {
    res.innerText = '✗ No match';
  }
}
&#13;
<p>Enter a number with ≥3 different digits</p>
<p><input type=text onkeyup='check(this.value)'> <span id=result></span></p>
&#13;
&#13;
&#13;

让我们把它分开:

^
(?=
    .*(.)       # Pick any character in the string as group 1
    (?!$|.*\1)  # Ensure this is not the last character, but is the last unique character
)
(?=
    .*(?!\1)(.) # Pick another character in the string as group 2
    (?!$|.*\2)  # Same condition as above 
)
[0-9]+
$

第一个条件确保有一个类似??1??a的字符串。第二个条件确保类似???2?b的字符串,其中1a2b12。由此我们可以得出结论,至少有3个不同的角色。

这可以很容易地推广到例如至少需要8个不同的角色:

^
(?=.*(.)(?!$|.*\1))
(?=.*(?!\1)(.)(?!$|.*\2))
(?=.*(?!\1|\2)(.)(?!$|.*\3))
(?=.*(?!\1|\2|\3)(.)(?!$|.*\4))
(?=.*(?!\1|\2|\3|\4)(.)(?!$|.*\5))
(?=.*(?!\1|\2|\3|\4|\5)(.)(?!$|.*\6))
(?=.*(?!\1|\2|\3|\4|\5|\6)(.)(?!$|.*\7))
[0-9]+
$

由于JavaScript最多只支持\9,因此您无法使用此方法检查超过10个不同的字符。在这一点上,你应该真正质疑正则表达式是否适合这项工作。

答案 1 :(得分:1)

你实际上可以使用正则表达式执行此操作,但它会非常难看并且几乎无法理解。

仅查看一个案例,我们可以为包含0,1的字符串写一个正则表达式,并且至少有一个从2到9的数字:

/^0(\d)*1(\d)*[2-9](\d)*$/

对于每对可能的数字,我们必须编写一个像这个广告的正则表达式,使用|将所有这些结合起来,以便我们捕获所有情况。

有10 * 9 = 90对不同的数字,每组有2个排列,总共180个组。

所以我们必须这样做:

/(^0(\d)*1(\d)*[2-9](\d)*$/)|(^0(\d)*2(\d)*(1|[3-9])(\d)*$/)| ... /

继续为所有180个团体。这将是一个巨大的正则表达式,并且可能需要很长时间才能编译。

您应该使用代码进行此验证,而不是运行正则表达式。

编辑:显然,JavaScript正则表达式具有一些扩展功能,可以实现这一点,即重用给定组捕获的值。请参阅@ kennytm的答案。

答案 2 :(得分:0)

根据否定前瞻,您可以确保不同的数字匹配三次:

(\d)\d*?((?!\1)\d)\d*?(?!\1|\2)\d+$

RegEx Demo

  • (?!\1)否定前瞻以确保下次匹配与捕获的组#1
  • 不同
  • (?!\1|\2)否定前瞻以确保下次匹配与捕获的组#1和组#2不同

答案 3 :(得分:0)

&#13;
&#13;
function uniqueDigit(str)
{
    var a = 0;
    for (var i=0; i<10; i++)
    {
        (new RegExp( i, 'g')).test(str) && a++;
    }
    return a
}
console.log(uniqueDigit('10122211100')) // in str
console.log(uniqueDigit(222111333888))  // in int
var a = 123456;
console.log(/^\d{6}$/.test(a) && uniqueDigit(a) > 2) // example
&#13;
&#13;
&#13;