Подсчет слов в строке

function WordCount(str) {
  var totalSoFar = 0;
  for (var i = 0; i < WordCount.length; i++)
    if (str(i) === " ") { // if a space is found in str
      totalSoFar = +1; // add 1 to total so far
  }
  totalsoFar += 1; // add 1 to totalsoFar to account for extra space since 1 space = 2 words
}

console.log(WordCount("Random String"));

Я думаю, что это довольно хорошо, за исключением того, что if утверждение неверно. Как мне сказать if(str(i) содержит пробел, добавьте 1.

Редактировать:

Я узнал (благодаря Blender), что могу сделать это с гораздо меньшим количеством кода:

function WordCount(str) { 
  return str.split(" ").length;
}

console.log(WordCount("hello world"));

32 ответа

Решение

Используйте квадратные скобки, а не круглые скобки:

str[i] === " "

Или же charAt:

str.charAt(i) === " "

Вы также можете сделать это с .split():

return str.split(' ').length;

Попробуйте это, прежде чем изобретать колеса

от Количество слов в строке, используя JavaScript

function countWords(str) {
  return str.trim().split(/\s+/).length;
}

с http://www.mediacollege.com/internet/javascript/text/count-words.html

function countWords(s){
    s = s.replace(/(^\s*)|(\s*$)/gi,"");//exclude  start and end white-space
    s = s.replace(/[ ]{2,}/gi," ");//2 or more space to 1
    s = s.replace(/\n /,"\n"); // exclude newline with a start spacing
    return s.split(' ').filter(function(str){return str!="";}).length;
    //return s.split(' ').filter(String).length; - this can also be used
}

Использование JavaScript для подсчета слов в строке, без использования регулярных выражений - это будет лучший подход

function WordCount(str) {
     return str.split(' ')
            .filter(function(n) { return n != '' })
            .length;
}

Примечания от автора:

Вы можете адаптировать этот скрипт для подсчета слов любым удобным вам способом. Важная часть s.split(' ').length - это подсчитывает пробелы. Скрипт пытается удалить все лишние пробелы (двойные пробелы и т. Д.) Перед подсчетом. Если текст содержит два слова без пробела между ними, он будет считаться одним словом, например "Первое предложение. Начало следующего предложения".

Еще один способ считать слова в строке. Этот код считает слова, которые содержат только буквенно-цифровые символы и символы "_", "'", "-", "'".

function countWords(str) {
  var matches = str.match(/[\w\d\’\'-]+/gi);
  return matches ? matches.length : 0;
}

После очистки строки вы можете сопоставить непробельные символы или границы слов.

Вот два простых регулярных выражения для захвата слов в строку:

  • Последовательность непробельных символов: /\S+/g
  • Допустимые символы между границами слова: /\b[a-z\d]+\b/g

В приведенном ниже примере показано, как извлечь количество слов из строки, используя эти шаблоны захвата.

/*Redirect console output to HTML.*/document.body.innerHTML='';console.log=function(s){document.body.innerHTML+=s+'\n';};
/*String format.*/String.format||(String.format=function(f){return function(a){return f.replace(/{(\d+)}/g,function(m,n){return"undefined"!=typeof a[n]?a[n]:m})}([].slice.call(arguments,1))});

// ^ IGNORE CODE ABOVE ^
//   =================

// Clean and match sub-strings in a string.
function extractSubstr(str, regexp) {
    return str.replace(/[^\w\s]|_/g, '')
        .replace(/\s+/g, ' ')
        .toLowerCase().match(regexp) || [];
}

// Find words by searching for sequences of non-whitespace characters.
function getWordsByNonWhiteSpace(str) {
    return extractSubstr(str, /\S+/g);
}

// Find words by searching for valid characters between word-boundaries.
function getWordsByWordBoundaries(str) {
    return extractSubstr(str, /\b[a-z\d]+\b/g);
}

// Example of usage.
var edisonQuote = "I have not failed. I've just found 10,000 ways that won't work.";
var words1 = getWordsByNonWhiteSpace(edisonQuote);
var words2 = getWordsByWordBoundaries(edisonQuote);

console.log(String.format('"{0}" - Thomas Edison\n\nWord count via:\n', edisonQuote));
console.log(String.format(' - non-white-space: ({0}) [{1}]', words1.length, words1.join(', ')));
console.log(String.format(' - word-boundaries: ({0}) [{1}]', words2.length, words2.join(', ')));
body { font-family: monospace; white-space: pre; font-size: 11px; }


В поисках уникальных слов

Вы также можете создать сопоставление слов, чтобы получить уникальный счет.

function cleanString(str) {
    return str.replace(/[^\w\s]|_/g, '')
        .replace(/\s+/g, ' ')
        .toLowerCase();
}

function extractSubstr(str, regexp) {
    return cleanString(str).match(regexp) || [];
}

function getWordsByNonWhiteSpace(str) {
    return extractSubstr(str, /\S+/g);
}

function getWordsByWordBoundaries(str) {
    return extractSubstr(str, /\b[a-z\d]+\b/g);
}

function wordMap(str) {
    return getWordsByWordBoundaries(str).reduce(function(map, word) {
        map[word] = (map[word] || 0) + 1;
        return map;
    }, {});
}

function mapToTuples(map) {
    return Object.keys(map).map(function(key) {
        return [ key, map[key] ];
    });
}

function mapToSortedTuples(map, sortFn, sortOrder) {
    return mapToTuples(map).sort(function(a, b) {
        return sortFn.call(undefined, a, b, sortOrder);
    });
}

function countWords(str) {
    return getWordsByWordBoundaries(str).length;
}

function wordFrequency(str) {
    return mapToSortedTuples(wordMap(str), function(a, b, order) {
        if (b[1] > a[1]) {
            return order[1] * -1;
        } else if (a[1] > b[1]) {
            return order[1] * 1;
        } else {
            return order[0] * (a[0] < b[0] ? -1 : (a[0] > b[0] ? 1 : 0));
        }
    }, [1, -1]);
}

function printTuples(tuples) {
    return tuples.map(function(tuple) {
        return padStr(tuple[0], ' ', 12, 1) + ' -> ' + tuple[1];
    }).join('\n');
}

function padStr(str, ch, width, dir) { 
    return (width <= str.length ? str : padStr(dir < 0 ? ch + str : str + ch, ch, width, dir)).substr(0, width);
}

function toTable(data, headers) {
    return $('<table>').append($('<thead>').append($('<tr>').append(headers.map(function(header) {
        return $('<th>').html(header);
    })))).append($('<tbody>').append(data.map(function(row) {
        return $('<tr>').append(row.map(function(cell) {
            return $('<td>').html(cell);
        }));
    })));
}

function addRowsBefore(table, data) {
    table.find('tbody').prepend(data.map(function(row) {
        return $('<tr>').append(row.map(function(cell) {
            return $('<td>').html(cell);
        }));
    }));
    return table;
}

$(function() {
    $('#countWordsBtn').on('click', function(e) {
        var str = $('#wordsTxtAra').val();
        var wordFreq = wordFrequency(str);
        var wordCount = countWords(str);
        var uniqueWords = wordFreq.length;
        var summaryData = [
            [ 'TOTAL', wordCount ],
            [ 'UNIQUE', uniqueWords ]
        ];
        var table = toTable(wordFreq, ['Word', 'Frequency']);
        addRowsBefore(table, summaryData);
        $('#wordFreq').html(table);
    });
});
table {
    border-collapse: collapse;
    table-layout: fixed;
    width: 200px;
    font-family: monospace;
}
thead {
    border-bottom: #000 3px double;;
}
table, td, th {
    border: #000 1px solid;
}
td, th {
    padding: 2px;
    width: 100px;
    overflow: hidden;
}

textarea, input[type="button"], table {
    margin: 4px;
    padding: 2px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<h1>Word Frequency</h1>
<textarea id="wordsTxtAra" cols="60" rows="8">Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.

Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.

But, in a larger sense, we can not dedicate -- we can not consecrate -- we can not hallow -- this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us -- that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion -- that we here highly resolve that these dead shall not have died in vain -- that this nation, under God, shall have a new birth of freedom -- and that government of the people, by the people, for the people, shall not perish from the earth.</textarea><br />
<input type="button" id="countWordsBtn" value="Count Words" />
<div id="wordFreq"></div>

Я думаю, что этот метод больше, чем вы хотите

var getWordCount = function(v){
    var matches = v.match(/\S+/g) ;
    return matches?matches.length:0;
}

String.prototype.match возвращает массив, мы можем проверить длину,

Я считаю этот метод наиболее описательным

var str = 'one two three four five';

str.match(/\w+/g).length;

Это довольно просто и точно подсчитывает слова, даже если между ними более одного пробела:

      return string.split(/\s+/).length;

Объяснение регулярного выражения

Это обработает все случаи и будет максимально эффективно. (Вы не хотите split(''), если заранее не знаете, что нет пробелов большей длины, чем один.):

var quote = `Of all the talents bestowed upon men, 
              none is so precious as the gift of oratory. 
              He who enjoys it wields a power more durable than that of a great king. 
              He is an independent force in the world. 
              Abandoned by his party, betrayed by his friends, stripped of his offices, 
              whoever can command this power is still formidable.`;

function WordCount(text) {
    text = text.trim();
    return text.length > 0 ? text.split(/\s+/).length : 0;
}
console.log(WordCount(quote));//59
console.log(WordCount('f'));//1
console.log(WordCount('  f '));//1
console.log(WordCount('   '));//0

Самый простой способ, который я нашел, это использовать регулярные выражения с split.

var calculate = function() {
  var string = document.getElementById('input').value;
  var length = string.split(/[^\s]+/).length - 1;
  document.getElementById('count').innerHTML = length;
};
<textarea id="input">My super text that does 7 words.</textarea>
<button onclick="calculate()">Calculate</button>
<span id="count">7</span> words

Ответ, данный @7-isnotbad, очень близок, но не учитывает строки из одного слова. Вот исправление, которое, кажется, учитывает каждую возможную комбинацию слов, пробелов и новых строк.

function countWords(s){
    s = s.replace(/\n/g,' '); // newlines to space
    s = s.replace(/(^\s*)|(\s*$)/gi,''); // remove spaces from start + end
    s = s.replace(/[ ]{2,}/gi,' '); // 2 or more spaces to 1
    return s.split(' ').length; 
}

Для тех, кто хочет использовать Lodash, можете использовать _.wordsфункция:

var str = "Random String";
var wordCount = _.size(_.words(str));
console.log(wordCount);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Here's my approach, which simply splits a string by spaces, then for loops the array and increases the count if the array[i] matches a given regex pattern.

    function wordCount(str) {
        var stringArray = str.split(' ');
        var count = 0;
        for (var i = 0; i < stringArray.length; i++) {
            var word = stringArray[i];
            if (/[A-Za-z]/.test(word)) {
                count++
            }
        }
        return count
    }

Invoked like so:

var str = "testing strings here's a string --..  ? // ... random characters ,,, end of string";
wordCount(str)

(added extra characters & spaces to show accuracy of function)

The str above returns 10, which is correct!

let leng = yourString.split(' ').filter(a => a.trim().length > 0).length
function countWords(str) {
    var regEx = /([^\u0000-\u007F]|\w)+/g;  
    return str.match(regEx).length;
}

Объяснение:

/([^\u0000-\u007F]|\w) соответствует символам слова - что здорово -> регулярное выражение делает тяжелую работу за нас. (Этот шаблон основан на следующем ответе SO: /questions/32020615/regulyarnoe-vyirazhenie-dlya-sootvetstviya-ne-anglijskim-simvolam/32020636#32020636 @Landeeyo)

+ соответствует всей строке ранее указанных символов слова - поэтому мы в основном группируем символы слова.

/g означает, что он продолжает смотреть до конца.

str.match(regEx) возвращает массив найденных слов - поэтому мы считаем его длину.

Точность тоже важна.

Вариант 3 в основном заменяет все пробелы, кроме любых, на +1 а затем оценивает это, чтобы подсчитать 1дает вам количество слов.

Это самый точный и самый быстрый метод из четырех, которые я использовал здесь.

Обратите внимание, это медленнее, чем return str.split(" ").length; но он точен по сравнению с Microsoft Word.

См. Файл ops / s и количество возвращенных слов ниже.

Вот ссылка для запуска этого стендового теста. https://jsbench.me/ztk2t3q3w5/1

// This is the fastest at 111,037 ops/s ±2.86% fastest
var str = "All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy.";
function WordCount(str) {
  return str.split(" ").length;
}
console.log(WordCount(str));
// Returns 241 words. Not the same as Microsoft Word count, of by one.

// This is the 2nd fastest at 46,835 ops/s ±1.76% 57.82% slower
var str = "All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy.";
function WordCount(str) {
  return str.split(/(?!\W)\S+/).length;
}
console.log(WordCount(str));
// Returns 241 words. Not the same as Microsoft Word count, of by one.

// This is the 3rd fastest at 37,121 ops/s ±1.18% 66.57% slower
var str = "All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy.";
function countWords(str) {
  var str = str.replace(/\S+/g,"\+1");
  return eval(str);
}
console.log(countWords(str));
// Returns 240 words. Same as Microsoft Word count.

// This is the slowest at 89 ops/s 17,270 ops/s ±2.29% 84.45% slower
var str = "All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy. All work and no play makes Jack a dull boy.";
function countWords(str) {
  var str = str.replace(/(?!\W)\S+/g,"1").replace(/\s*/g,"");
  return str.lastIndexOf("");
}
console.log(countWords(str));
// Returns 240 words. Same as Microsoft Word count.

Возможно, есть более эффективный способ сделать это, но это то, что сработало для меня.

function countWords(passedString){
  passedString = passedString.replace(/(^\s*)|(\s*$)/gi, '');
  passedString = passedString.replace(/\s\s+/g, ' '); 
  passedString = passedString.replace(/,/g, ' ');  
  passedString = passedString.replace(/;/g, ' ');
  passedString = passedString.replace(/\//g, ' ');  
  passedString = passedString.replace(/\\/g, ' ');  
  passedString = passedString.replace(/{/g, ' ');
  passedString = passedString.replace(/}/g, ' ');
  passedString = passedString.replace(/\n/g, ' ');  
  passedString = passedString.replace(/\./g, ' '); 
  passedString = passedString.replace(/[\{\}]/g, ' ');
  passedString = passedString.replace(/[\(\)]/g, ' ');
  passedString = passedString.replace(/[[\]]/g, ' ');
  passedString = passedString.replace(/[ ]{2,}/gi, ' ');
  var countWordsBySpaces = passedString.split(' ').length; 
  return countWordsBySpaces;

}

он способен распознавать все следующее как отдельные слова:

abc,abc = 2 слова,
abc/abc/abc = 3 слова (работает с прямой и обратной косой чертой),
abc.abc = 2 слова,
abc[abc]abc = 3 слова,
abc;abc = 2 слова,

(некоторые другие предложения, которые я пробовал считать каждый пример как только 1 x слово) это также:

  • игнорирует все начальные и конечные пробелы

  • подсчитывает одну букву, за которой следует новая строка, как слово, которое, как я обнаружил, некоторые из предложений, приведенных на этой странице, не учитываются, например:





    иногда считается как 0 x слов, а другие функции считают только 1 x словом вместо 5 x слов)

если у кого-то есть идеи, как его улучшить или сделать его чище / эффективнее - добавьте, пожалуйста, 2 цента! Надеюсь, это поможет кому-то.

Я думаю, что этот ответ даст все решения для:

  1. Количество символов в данной строке
  2. Количество слов в заданной строке
  3. Количество строк в данной строке

 function NumberOf() { 
   var string = "Write a piece of code in any language of your choice that computes the total number of characters, words and lines in a given text. \n This is second line. \n This is third line.";

   var length = string.length; //No of characters
   var words = string.match(/\w+/g).length; //No of words
   var lines = string.split(/\r\n|\r|\n/).length; // No of lines

   console.log('Number of characters:',length);
   console.log('Number of words:',words);
   console.log('Number of lines:',lines);


}

NumberOf();

  1. Сначала вам нужно найти длину заданной строки по string.length
  2. Затем вы можете найти количество слов, сопоставив их со строкой string.match(/\w+/g).length
  3. Наконец, вы можете разбить каждую строку, как это string.length(/\r\n|\r|\n/).length

Я надеюсь, что это может помочь тем, кто ищет эти 3 ответа.

Я не уверен, если это было сказано ранее, или это то, что нужно здесь, но не могли бы вы сделать строку массивом, а затем найти длину?

let randomString = "Random String";

let stringWords = randomString.split(' ');
console.log(stringWords.length);

Этот фрагмент кода вычислит, сколько слов в предложении:

Вот функция, которая считает количество слов в HTML-коде:

$(this).val()
    .replace(/((&nbsp;)|(<[^>]*>))+/g, '') // remove html spaces and tags
    .replace(/\s+/g, ' ') // merge multiple spaces into one
    .trim() // trim ending and beginning spaces (yes, this is needed)
    .match(/\s/g) // find all spaces by regex
    .length // get amount of matches
      var str =   "Lorem ipsum dolor sit amet consectetur adipisicing elit. Labore illum fuga magni exercitationem porro? Eaque tenetur tempora nesciunt laborum deleniti, quidem nemo consequuntur voluptate alias ad soluta, molestiae, voluptas libero!" ;

let count = (str.match(/\s/g) || []).length;
console.log(count + 1 );

countWords =(str )=>{

    let count =  ( str.match(/\s/g)   || []  ).length;
    count = (count == 0 ) ? 0 : count +1  ; 
    return count 
}
      function countWords(str) {
    str = str.replace(/(^\s*)|(\s*$)/gi,"");
    str = str.replace(/[ ]{2,}/gi," ");
    str = str.replace(/\n /,"\n");
    return str.split(' ').length;
}
document.write(countWords("  this function remove extra space and count the real   string lenth"));

Адаптировано из внутреннего ответа.Он также обрабатывает крайний случай ''

      export const countWords = (str: string) => {

  str = str.trim();
  if (!str.length) {
    return str.length
  }
  return str.trim().split(/\s+/).length;
}

Шут-тесты

          test("countwords", () => {
        expect(countWords('  ')).toBe(0)
        expect(countWords('78   7 ')).toBe(2)
        expect(countWords('78 7 ')).toBe(2)
        expect(countWords('aa, , 7')).toBe(3)
        expect(countWords('aa, , \n \n \t 7 \n 4')).toBe(4)
    }); 

Если вы хотите посчитать конкретные слова

      function countWholeWords(text, keyword) {
    const times = text.match(new RegExp(`\\b${keyword}\\b`, 'gi'));

    if (times) {
        console.log(`${keyword} occurs ${times.length} times`);
    } else {
        console.log(keyword + " does not occurs")
    }
}


const text = `
In a professional context it often happens that private or corporate clients corder a publication to be 
made and presented with the actual content still not being ready. Think of a news blog that's 
filled with content hourly on the day of going live. However, reviewers tend to be distracted 
by comprehensible content, say, a random text copied from a newspaper or the internet.
`

const wordsYouAreLookingFor = ["random", "cat", "content", "reviewers", "dog", "with"]

wordsYouAreLookingFor.forEach((keyword) => countWholeWords(text, keyword));


// random occurs 1 times
// cat does not occurs
// content occurs 3 times
// reviewers occurs 1 times
// dog does not occurs
// with occurs 2 times

Я знаю, что уже поздно, но это регулярное выражение должно решить вашу проблему. Это будет соответствовать и вернуть количество слов в вашей строке. Скорее то, которое вы отметили как решение, которое будет считать пространство-пространство-слово двумя словами, хотя на самом деле это всего лишь одно слово.

function countWords(str) {
    var matches = str.match(/\S+/g);
    return matches ? matches.length : 0;
}
function WordCount(str) {
    var totalSoFar = 0;
    for (var i = 1; i < str.length; i++) {
        if (str[i] === " ") {
            totalSoFar ++;
        }
    }
    return totalSoFar; 
}
console.log(WordCount("hi my name is raj));

Проблема со стандартом/s+/Метод заключается в том, что он не работает со словами, написанными через дефис. Я пытался сделать это как одно регулярное выражение (/\s+|\w-\w/и несколько вариантов), но он не прошел многочисленные тесты, особенно из-за перекрывающихся совпадений. В итоге я остановился на следующем:

      function wordcount(s) {
    return s.replace(/-/g, ' ').trim().split(/\s+/g).length;
}

Он проходит следующие тесты:

      const test_sentences = [
    { sentence: "hello world.", word_count: 2 },
    { sentence: "hello world - how are you", word_count: 5 },
    { sentence: "hello 10 world - how are you?", word_count: 6 },
    { sentence: "   hello 10 world - how are you? 10   ", word_count: 7 },
    { sentence: "Test of-hyphens in a-string", word_count: 6 },
    { sentence: "Test of-hyphens -- in an-string ---", word_count: 6 },
    { sentence: "Test-of-hyphens -- in-a-string ---", word_count: 6 },
]
for (let s of test_sentences) {
    console.assert(wordcount(s.sentence) === s.word_count, `Expected ${s.word_count} but got ${wordcount(s.sentence)} for "${s.sentence}"`);
}

Вы можете использовать этот алгоритм:

app.js:

      const TextArea = document.querySelector('textarea');

const CountContainer = document.querySelector('#demo');


TextArea.addEventListener('keypress', () => {
    let TextValue = TextArea.value.split(' ').join('-').split('\n').join('-').split('-');

    let WordCountArray = TextValue.filter(el => {
        return el != '';
    });

    let WordSen = WordCountArray.length <= 1 ? 'Word' : 'Words';

    console.log(WordCountArray);

    CountContainer.textContent = WordCountArray.length + ' ' + WordSen;

});

TextArea.addEventListener('keyup', function () {
    if (this.value === '') CountContainer.textContent = '0 Word';
});

Индексная страница HTML для теста:

      <!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <textarea cols="30" rows="10"></textarea>
    <div id="demo"></div>

    <script src="app.js"></script>
</body>


</html>

В вашем коде есть ошибки.

function WordCount(str) {
    var totalSoFar = 0;
    for (var i = 0; i < str.length; i++) {
        if (str[i] === " ") {
            totalSoFar += 1;
        }
    }
    return totalSoFar + 1; // you need to return something.
}
console.log(WordCount("Random String"));

Есть еще один простой способ использования регулярных выражений:

(text.split(/\b/).length - 1) / 2

Точное значение может отличаться примерно на 1 слово, но оно также учитывает границы слов без пробела, например "word-word.word". И он не учитывает слова, которые не содержат букв или цифр.

<textarea name="myMessage" onkeyup="wordcount(this.value)"></textarea>
<script type="text/javascript">
var cnt;
function wordcount(count) {
var words = count.split(/\s/);
cnt = words.length;
var ele = document.getElementById('w_count');
ele.value = cnt;
}
document.write("<input type=text id=w_count size=4 readonly>");
</script>
Другие вопросы по тегам