如何使用javascript查找字符串中是否包含特定数量的连续连续数字?

时间:2015-06-19 00:56:55

标签: javascript regex

假设我想知道一个字符串是否包含5个或更多连续的连续数字。

var a = "ac39270982"; // False
var a = "000223344998"; // False
var a = "512345jj7"; // True - it contains 12345
var a = "aa456780"; // True - it contains 45678

是否有可用于实现此目的的RegEx?它是否也能够在以下情况下工作?

var a = "5111213141587"; // True

这应该是真的,因为它包含11,12,13,14,15。

我不确定是否可以检查提供的示例(单位数,两位数字)以及更大的数字(三位数等)。

4 个答案:

答案 0 :(得分:3)

我花时间为您的问题制作了100%Javascript方法。我只是解析字符串中的每个字符并进行仅整数比较。这不仅适用于五个连续的整数,但它也适用于检查十分之一(10年代,20年代等)。如果您愿意,您还可以增加/减少比较次数。

一个公平的警告:尽管这种方法在编码以寻找各种数字大小时可能具有可扩展性,但您仍然受到计算能力和比较次数的限制。这就是为什么我只提供单位数和十位数的代码,我让你/社区决定如何从这里扩展。

jsFiddle

如果您碰巧需要更多有关其工作原理的细节,请告诉我,我可以进一步澄清其内部运作。

var str = "1111122asdgas222*&^%121314151617bdjfjahdi234bdce56789";
var consecutive = 5; // Number of comparisons

// Single digits
alert("It is " + consecutiveDigits(str, consecutive) + " that " + str + " contains " + consecutive + " consecutive digits.");
// Tenths digits
alert("It is " + consecutiveDigits(str, consecutive) + " that " + str + " contains " + consecutive + " consecutive tenths.");

function consecutiveDigits(str, consecutive){
    var curr,
        prev,
        count = 0;
    for(var i = 0; i < str.length; ++i) {
        curr = parseInt(str.split('')[i]);
        if(isNumeric(curr)) {
            if(count === 0){
                ++count;
            }
            else if(prev + 1 === curr){
                ++count;
                if(count === consecutive){
                    return true;
                }
            }
            prev = curr;
        }
    }
    return false;
}

function consecutiveTenths(str, consecutive, iterations){
    var curr,
        prev,
        curr_tenth = 0,
        prev_tenth = 0,
        count = 0,
        count_tenth = 0;

    for(var i = 0; i < str.length; ++i) {
        curr = parseInt(str.split('')[i]);
        if(isNumeric(curr)) {
            ++count;
            if(count === iterations){
                curr_digit = (prev * 10) + curr;
                alert(count_digit + " " + curr_digit + " " + prev_tenth);
                if(count_digit === 0){
                    ++count_digit;
                }
                else if(curr_tenth === (prev_tenth + 1)){
                    ++count_digit;
                    if(count_digit === consecutive){
                        return true;
                    }
                }
                prev_digit = curr_digit;
                count = 0;
            }
            else {
                prev = curr;
            }
        }
        else {
            count = 0;
        }
    }
}


function isNumeric(n) {
    return !isNaN(parseFloat(n)) && isFinite(n);
}

答案 1 :(得分:2)

编辑:添加了代码段&amp;修复了numRegex中的错误

要回答一般情况(即任意长度数字的连续序列),你可以这样做:

http://jsfiddle.net/ksgLzL9u/8/

&#13;
&#13;
/* Find a sequence of n > 1 contiguously increasing integers in input
 * 
 * If sequence is found, return an object:
 *   {
 *     start:  <starting index of the sequence in input>,
 *     length: <length of the found sequence string>,
 *     first:  <first number in the sequence>
 *   }
 *
 * Otherwise, return null
 */
function findSequence(input, n) {
  var numRegex = /^(?:0|[1-9][0-9]*)$/;

  // Try every starting position
  for (var i = 0; i < input.length; ++i) {
    // At the current starting position, try every length for the 1st number
    for (var firstLen = 1; i + firstLen < input.length - 1; ++firstLen) {
      var afterFirst = i + firstLen;
      var first = input.slice(i, afterFirst);
      
      // If the first string isn't an integer, move on
      if (!numRegex.test(first)) {
        continue;
      }

      // Convert the first string to an integer
      var firstInt = parseInt(first, 10);

      // Build what the rest of the string should look like following the
      // first, in order to get a valid sequence
      var rest = "";
      for (var j = 1; j < n; ++j) {
        rest = rest.concat(firstInt + j);
      }

      // Compare to what actually follows the starting string; if it
      // matches, then we have our sequence; otherwise, continue on
      if (input.slice(afterFirst, afterFirst + rest.length) === rest) {
          return {
            start: i,
            length: first.length + rest.length,
            first: first
          };
      }
    }
  }
  return null;
}

$(function() {
  function processChange() {
    var input = $('#input').val();
    var n = parseInt($('#n').val());
      
    if (n > 1 && input.length) {
      var result = findSequence(input, n);
      if (result) {
        $('#result').text(JSON.stringify(result, null, 2));
        var afterFirst = result.start + result.first.length;
        var afterSeq = result.start + result.length;
        $('#highlighted').empty()
          .append($('<span/>')
                    .text(input.slice(0, result.start)))
          .append($('<span/>')
                    .addClass('sequence')
                    .append($('<span/>')
                              .addClass('first')
                              .text(result.first))
                    .append($('<span/>')
                              .text(input.slice(afterFirst, afterSeq))))
          .append($('<span/>')
                    .text(input.slice(afterSeq)));
      } else {
        $('#result').text("No sequence found");
        $('#highlighted').empty();
      }
    } else {
      $('#result').text("");
      $('#highlighted').empty();
    }
  }
  
  $('input,n').on("keyup mouseup", processChange);
  processChange();
});
&#13;
#input {
    width: 50%;
    min-width: 200px;
}

#n {
    width: 50px;
}

.highlighted-result {
    font-family: monospace;
}

.highlighted-result .sequence {
    background-color: yellow;
}

.highlighted-result .first {
    border: solid black 1px;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<h1>Input</h1>
<div>
  <input id="input" type="text" value="111121314155" placeholder="input">
  <input id="n" type="number" value="5" placeholder="n">
</div>
<h1>Results</h1>
<div id="highlighted" class="highlighted-result"></div>
<pre id="result"></pre>
&#13;
&#13;
&#13;

我还没有尝试优化解决方案(例如,firstLen迭代可能会被短路,并且整个rest字符串不需要构建),但我保持原样使算法更清晰。

答案 2 :(得分:1)

您可以构建regexp来验证它是否为真,但您可能很难检索整个连续的字符串。这就说RegExp会有点麻烦,但你可以创建一个函数来创建所需的正则表达式,具体取决于所需的参数。请参阅代码段:

function build_regexp(n) {
  var string = "";
  for (var i = 0; i <= 14 - n; i++) {
    var start_num = i
    for (var j = 0; j < n; j++) {
      string += (start_num++).toString()

    }
    string += "|";
  }
  string = string.replace(/\|$/, '');
  return string
}


document.getElementById('check').onclick = function() {
  var regex = new RegExp(build_regexp(document.getElementById('cons').value), "g");
  document.getElementById('regex').textContent = regex;
  document.getElementById('result').innerHTML = (regex.exec(document.getElementById('to_check').value) || "false")
}
<div id="regex"></div>
<div>Enter wanted consecutive numbers: <input id="cons"></input></div>
<div>Enter string to check: <input id="to_check"></input></div>
<button id="check">check</button>
<div id="result"></div>

答案 3 :(得分:1)

使用正则表达式很难做到这一点,但这是一个尝试:

  • 一位数字

    (?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){4,}\d
    

    https://regex101.com/r/mw4bvG/1

  • 两位数字

    (?:(\d)(?:0(?=(?:\1)1)|1(?=(?:\1)2)|2(?=(?:\1)3)|3(?=(?:\1)4)|4(?=(?:\1)5)|5(?=(?:\1)6)|6(?=(?:\1)7)|7(?=(?:\1)8)|8(?=(?:\1)9))|09(?=10)|19(?=20)|29(?=30)|39(?=40)|49(?=50)|59(?=60)|69(?=70)|79(?=80)|89(?=90)){4,}\d{2}
    

    https://regex101.com/r/Kcl9FC/1

  • 三位数

    (?:(\d{2})(?:0(?=(?:\1)1)|1(?=(?:\1)2)|2(?=(?:\1)3)|3(?=(?:\1)4)|4(?=(?:\1)5)|5(?=(?:\1)6)|6(?=(?:\1)7)|7(?=(?:\1)8)|8(?=(?:\1)9))|(\d)(?:09(?=(?:\2)10)|19(?=(?:\2)20)|29(?=(?:\2)30)|39(?=(?:\2)40)|49(?=(?:\2)50)|59(?=(?:\2)60)|69(?=(?:\2)70)|79(?=(?:\2)80)|89(?=(?:\2)90))|099(?=100)|199(?=200)|299(?=300)|399(?=400)|499(?=500)|599(?=600)|699(?=700)|799(?=800)|899(?=900)){4,}\d{3}
    

    https://regex101.com/r/joeWdR/1

  • 在一起

    (?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){4,}\d|(?:(\d)(?:0(?=(?:\1)1)|1(?=(?:\1)2)|2(?=(?:\1)3)|3(?=(?:\1)4)|4(?=(?:\1)5)|5(?=(?:\1)6)|6(?=(?:\1)7)|7(?=(?:\1)8)|8(?=(?:\1)9))|09(?=10)|19(?=20)|29(?=30)|39(?=40)|49(?=50)|59(?=60)|69(?=70)|79(?=80)|89(?=90)){4,}\d{2}|(?:(\d{2})(?:0(?=(?:\2)1)|1(?=(?:\2)2)|2(?=(?:\2)3)|3(?=(?:\2)4)|4(?=(?:\2)5)|5(?=(?:\2)6)|6(?=(?:\2)7)|7(?=(?:\2)8)|8(?=(?:\2)9))|(\d)(?:09(?=(?:\3)10)|19(?=(?:\3)20)|29(?=(?:\3)30)|39(?=(?:\3)40)|49(?=(?:\3)50)|59(?=(?:\3)60)|69(?=(?:\3)70)|79(?=(?:\3)80)|89(?=(?:\3)90))|099(?=100)|199(?=200)|299(?=300)|399(?=400)|499(?=500)|599(?=600)|699(?=700)|799(?=800)|899(?=900)){4,}\d{3}
    

    https://regex101.com/r/NyCLh6/1