Статьи

Подсчет настоящих слов с помощью Ruby

Руки показывают цифры от одного до пяти.

,

Подожди минутку, ты имеешь в виду, что это сообщение в блоге просто о подсчете слов в документе? Во-первых, это достаточно просто, а во-вторых, это может сделать любой текстовый процессор на лету.

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

Позвольте мне прояснить этот момент немного дальше. Когда текстовый процессор считает слова, он использует пробел в качестве разделителя. В результате, то, что придет после этого, будет считаться новым словом и включаться в подсчет слов.

Что делать, если у вас есть номер, отдельное письмо, адрес электронной почты и т. Д.? Считаете ли вы эти слова? Я не. Текстовые процессоры не дают вам возможность фильтровать подсчитанные слова.

Например, в небольшом эксперименте, который я провел с Microsoft Word, я ввел следующий текст:

Ruby 1 2 3 " email@email.com

Количество слов было 6 !

Ну, что мы подразумеваем под словом в любом случае? Как определено на веб-сайте Оксфордских словарей , слово:

Отдельный значимый элемент речи или письма, используемый вместе с другими (или иногда один) для формирования предложения и обычно показывается с пробелом с обеих сторон при написании или печати

Глядя на это определение, количество слов в приведенном выше тексте должно быть равно 1, а не 6. Что нам делать в этом случае? Мощь и гибкость Ruby могут помочь вам в этом.

Давайте углубимся в учебник и посмотрим, как мы можем сказать Руби, что и что не следует рассматривать на практике как слова.

OMIM ® — онлайн менделевское наследование в человеке ®

В начале 1960-х годов доктор Виктор МакКусик создал базу данных, которая служила каталогом менделевских черт и расстройств. В то время его называли менделевским наследием в человеке (MIM). Онлайн-версия OMIM ® , представляющая собой всеобъемлющий сборник человеческих генов и генетических фенотипов , обновляется ежедневно и доступна бесплатно. Он был создан в 1985 году и стал доступен в Интернете с 1987 года. Текст OMIM содержит информацию обо всех известных менделевских расстройствах и более 15 000 генов.

Что ж, эти ценные данные — то, с чем мы будем работать в этом уроке!

Получить файл OMIM ®

На этом этапе мы будем загружать текстовый файл OMIM ® , который можно получить, выполнив следующие действия:

  1. Перейдите по этому анонимному ftp-адресу: ftp://ftp.ncbi.nih.gov . У вас должно появиться диалоговое окно, которое выглядит примерно так:

dialogueBox

Выберите « Гость» рядом с « Подключить как:» , а затем нажмите кнопку «Подключить *», и в этом случае вы увидите следующий каталог:

каталог

Нам нужен текстовый файл omim.txt.Z (66,3 МБ), который можно найти в каталоге / repository / OMIM / ARCHIVE .

Разархивируйте файл, чтобы получить omim.txt (151,2 МБ).

Подсчет количества слов

Имея текстовый файл, с которым мы хотим работать, давайте напишем скрипт на Ruby, который будет возвращать количество слов (традиционный способ подсчета). Сценарий выполнения этой задачи может быть записан следующим образом:

 text = File.open('omim.txt', 'r')
number_of_words = 0
text.each_line(){ |line| number_of_words = number_of_words + line.split.size }
puts number_of_words

Вы должны получить это большое число: 22451516

Считая только то, что вы считаете словами

В этом разделе я продемонстрирую некоторые сценарии того, как мы можем указать Ruby, что следует считать словами, а какие нет.

Сценарий 1: не относитесь к автономным числам как к словам

Как упоминалось ранее, Microsoft Word возвратил 6 в качестве количества слов для: Ruby 1 2 3 " [email protected]

Таким образом, он рассматривал числа как слова. Давайте исправим это с помощью Ruby. Регулярные выражения очень удобны для указания Ruby о том, что мы подразумеваем под автономными числами. Я немного обсуждаю регулярные выражения в одной из моих других публикаций в блоге: « Охота на последовательность генов» .

Давайте рассмотрим это шаг за шагом. Первое, что мы хотим сделать, это указать начало и конец строки ( т.е. ту часть, которую мы хотим видеть, чтобы считаться словом). В этом случае мы можем использовать \A\Z

После этого мы хотим указать, что числу может предшествовать знак минус (-) или знак плюс (+). Это можно записать как [- +]

Хороший символ, который мы можем использовать в регулярных выражениях, является символом вопросительного знака ? , Символ знака вопроса просто говорит нам, чтобы соответствовать ноль или один из предыдущих символов. Например, если мы напишем: [- +]? , это означает, что значению может предшествовать либо -+

Теперь мы бы хотели, чтобы регулярное выражение имело ноль или более числовых значений. Это можно записать как [0-9]* Итак, у нас есть значения в диапазоне 0-9, а звездочка * Таким образом, если у нас нет числового значения, это нормально. У нас также могут быть значения, такие как 01, 6, 9, 54, 565346 и т. Д.

Поскольку у нас могут быть числа с плавающей запятой, мы можем встретить точку . в некоторых значениях ( т. е. 5,43). Добавление \.? регулярное выражение говорит, что . не является обязательным, но будет принято во внимание, если он появится (ноль или более от предыдущего символа).

Наконец, с . будет следовать значение, мы можем использовать: [0-9]+ Символ +один или несколько (но не ноль) предыдущих символов.

Последнее регулярное выражение для проверки наличия числового значения теперь выглядит следующим образом: \A[-+]?[0-9]*\.?[0-9]+\Z

Сценарий 2: не относитесь к отдельным буквам как к словам

Следующий сценарий, который мы хотим рассмотреть, — это случай, когда в документе есть отдельные буквы ( т. Е. A, b, c, D).

Это можно просто сделать с помощью этого регулярного выражения: ^[a-zA-Z]$ Знак ^$

Сценарий 3: не рассматривайте адреса электронной почты как слова

Это может быть немного сложно, но давайте рассмотрим шаг за шагом.

Позвольте мне представить вам \w+ \w+одному или нескольким символам слова. Это может быть эквивалентно [a-zA-Z0-9_]+ Нам это нужно, поскольку часть письма может содержать такой шаблон.

За шаблоном выше может следовать любой символ. В регулярных выражениях точка . означает любой персонаж . Таким образом, сообщение регулярному выражению о том, что оно может содержать любой символ слова или тире -[\w+\-].? ,

Вся часть регулярного выражения, которая проверяет, есть ли у нас адрес электронной почты:

 \A([\w+\-].?)+@[a-z0-9\-]+(\.[a-z]+)*\.[a-z]+\Z

В целом

Давайте теперь посмотрим, как работает наш скрипт на Ruby, включая три приведенных выше сценария:

 text = File.open('omim.txt', 'r')
number_of_words = 0
standalone_number = /\A[-+]?[0-9]*\.?[0-9]+\Z/
standalone_letter = /^[a-zA-Z]$/
email_address = /\A([\w+\-].?)+@[a-z0-9\-]+(\.[a-z]+)*\.[a-z]+\Z/
text.each_line(){ |line| number_of_words = number_of_words + line.split.count {|word|  word !~ standalone_number && word !~ standalone_letter && word !~  email_address }}
puts number_of_words

Запустив скрипт (это займет некоторое время), количество слов у нас будет: 21636153

,

Вы заметили разницу между подсчетом слов в целом и использованием нашего сценария Ruby? Это разница в 815 363 слова! Вот это да!

Слишком много исключений, означающих, что некоторые законные слова рубятся? Уточните приведенные выше регулярные выражения, чтобы скрипт работал на вас и на то, что вы считаете словами.

Удачи!