Я не уверен, что разбиение на массив - это самый эффективный способ памяти, особенно для очень больших текстов.Если у вас есть текстовый файл размером в несколько мегабайт, вы создадите очень большой массив, который будет использовать много памяти.
Вместо этого я бы сделал что-то вроде этого:
while ($text = <>) {
while ($text =~ /([A-Za-z\-]+)/g) {
my $word = lc($1); # dont diffrentiate between 'Dog' and 'dog'
$count++; # total word count
$wordCount{$word}++; # individual word count
}
}
Кроме того, можно легко добавлять новые символы, если вы обнаружите, что хотите добавить в слово допустимые символы.То есть, если вы думаете, что this_file
будет приемлемым, измените символы на [A-Za-z\-_]
.
Что касается ваших вопросов:
Регулярное выражение \W*\s+W*
означает: соответствует нулевому символу без словалюбое количество раз, после которого следует один для любого количества пробелов, после которого следует ноль для любого количества несловесных символов.Довольно странный способ разделения, но он в основном разделит все пробелы и удалит все несловарные символы в процессе для более точного индивидуального подсчета слов.(Например, он не будет трактовать dog,
и dog
как два разных слова).
Сам по себе grep
вернет список значений, соответствующих регулярному выражению.Регулярное выражение будет соответствовать любому значению массива в @words
, которое состоит только из (от начала до конца) букв, верхнего или нижнего регистра и дефиса.Если внутри значения есть какой-либо другой символ, grep исключит его.
Ошибка в том, что "dog.rose"
и "fox."
не будут разделены правильно, потому что нет пробелов.Поэтому они не будут неявно очищены от несловесных символов и, следовательно, будут удалены с помощью grep.