Как я могу получить регулярное выражение, чтобы найти каждое совпадение в JavaScript?

Если я запускаю это:

'121'.match(/[0-9]{2}/gi)

Я возвращаю массив с единственным результатом:

['12']

Как я могу заставить его вернуть все результаты, даже если они перекрываются? Я хочу, чтобы результат был таким:

['12', '21']

РЕДАКТИРОВАТЬ: Или лучший пример будет:

'1234567'.match(...);

должен дать мне массив с

[12, 23, 34, 45, 56, 67]

5 ответов

Решение

Это просто не будет работать так, как вы хотите.

когда вы указываете шаблон [0-9]{2}, match() сначала ищет двухзначное число, а затем продолжает поиск с этого места. так как длина строки равна 3, очевидно, он не найдет другого совпадения.

Вы должны использовать другой алгоритм для поиска всех двухзначных чисел. Я бы предложил использовать комбинацию из вашего первого матча и сделать еще один со следующим регулярным выражением

/[0-9]([0-9]{2})/ и объединить наборы как первого, так и второго запуска.

Это работает с большинством двигателей pcre.
Захват 2, потреблять 1.

/(?=(\d\d))\d/g

Я новичок в JavaScript. Это работает:

var pat = /(?=(\d\d))\d/g;
var results = [];
var match;

while ( (match = pat.exec( '1234567' ) ) != null ) { 
  results.push( match[1] );
}

print (results);

Выход: 12,23,34,45,56,67

Вы можете сделать это так:

var str = '121';
var results = [];
var re = /[0-9]{2}/gi, matches;
while (matches = re.exec(str)) {
    results.push(matches[0]);
    re.lastIndex -= (matches[0].length - 1);  // one past where it matched before
}
// results is an array of matches here

Требуется несколько звонков .exec() и тогда вы должны манипулировать .lastIndex значение, чтобы оно началось там, где вы хотите, чтобы оно снова выглядело.

Вы можете увидеть, как это работает здесь: http://jsfiddle.net/jfriend00/XsNe5/.

Вы можете прочитать о том, как звонить .exec() Несколько раз работает здесь: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/RegExp/exec.

Вот еще один пример использования lookaheads

var str = "12345",
    regexp = /\d(?=(\d))/g,
    results = [],
    m = null;

while(m = regexp.exec(str)) results.push(m.join(''));

alert(results) // 12,23,34,45

Та же идея, что и в ruakh, но немного другой подход.

Это не очень кратко, но это:

var matches = [];
'1234567'.replace
(
  /(?=[0-9]{2})/gi,
  function(s,pos,str)
  {
    matches.push(str.substr(pos, 2));
  }
);

установит matches в ['12','23','34','45','56','67'], Он работает, используя утверждение для поиска совпадений, фактически не проглатывая их. (The replace на самом деле ничего не заменяет в этом случае; это просто удобный способ применить замыкание ко всем экземплярам регулярного выражения в данной строке.)

Другие вопросы по тегам