Очень близко: вы можете использовать String#match
, чтобы сделать это:
var count = "This is a test text".match(/te/g).length;
Использует регулярное выражение /te/g
(ищите «te» буквально, глобально) и просит строку вернуть массив совпадений. Длина массива равна количеству.
Естественно, это создает промежуточный массив, который может быть не идеальным, если у вас большой набор результатов. Если вы не возражаете против зацикливания:
function countMatches(str, re) {
var counter;
counter = 0;
while (re.test(str)) {
++counter;
}
return counter;
}
var count = countMatches("This is a test text", /te/g);
Использует RegExp#test
для поиска совпадений без создания промежуточных массивов. (Спасибо kennebec за комментарий, указывающий, что мое более раннее использование RegExp#exec
в вышеупомянутых созданных промежуточных массивах излишне!) То, будет ли это более эффективным, будет полностью зависеть от того, сколько из них вы ожидаете найти, версия, создающая один большой массив, вероятно, будет оптимизирована в рамках вызова String#match
и, следовательно, будет быстрее за счет большего (временного) использования памяти & mdash; большой набор результатов может затормозиться при попытке выделить память, но малый вряд ли удастся.
Редактировать Прокомментируйте ваш комментарий ниже, если вы не ищете паттернов и не возражаете против зацикливания, вы можете сделать это вместо этого:
function countMatches(str, substr) {
var index, counter, sublength;
sublength = substr.length;
counter = 0;
for (index = str.indexOf(substr);
index >= 0;
index = str.indexOf(substr, index + sublength))
{
++counter;
}
return counter;
}
var count = countMatches("This is a test text", "te");
Я не знаю заранее обожженного без RegExp способа сделать это.