Подсчитать количество предложений Ruby

Мне довелось искать повсюду, и мне не удалось найти решение для подсчета количества предложений в строке с использованием Ruby. Кто-нибудь как это сделать?

Пример

string = "The best things in an artist’s work are so much a matter of intuition, that there is much to be said for the point of view that would altogether discourage intellectual inquiry into artistic phenomena on the part of the artist. Intuitions are shy things and apt to disappear if looked into too closely. And there is undoubtedly a danger that too much knowledge and training may supplant the natural intuitive feeling of a student, leaving only a cold knowledge of the means of expression in its place. For the artist, if he has the right stuff in him ... "

Эта строка должна возвращать число 4.


person ikanyu    schedule 08.09.2015    source источник
comment
stackoverflow.com/a/18089658/517483 может помочь.   -  person Amit Patel    schedule 08.09.2015
comment
Как вы определяете предложение?   -  person Stefan    schedule 08.09.2015


Ответы (3)


Вы можете разделить текст на предложения и посчитать их. Здесь:

string.scan(/[^\.!?]+[\.!?]/).map(&:strip).count # scan has regex to split string and strip will remove trailing spaces.
# => 4 

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

[^\.!?]

Каретка внутри класса символов [^ ] является оператором отрицания. Это означает, что мы ищем символы, которых нет в списке: ., ! и ?.

+

является жадным оператором, который возвращает совпадения от 1 до неограниченного количества раз. (сохраняем наши предложения здесь и игнорируем повторы вроде ...)

[\.!?]  

соответствующие символы ., ! или ?.

Короче говоря, мы захватываем все символы, отличные от ., ! или ?, пока не получим символы ., ! или ?. Что в принципе можно рассматривать как предложение (в широком смысле).

person shivam    schedule 08.09.2015
comment
Для подсчета элементов в массиве вам на самом деле не нужно .map(&:strip) здесь :) - person Alexey Shein; 08.09.2015
comment
Не могли бы вы объяснить свое регулярное выражение? Может быть не очевидно, что он делает. - person Stefan; 08.09.2015

Я думаю, имеет смысл рассматривать слово char, за которым следует ?! или ., как разделитель предложения:

string.strip.split(/\w[?!.]/).length
#=> 4

Поэтому я не рассматриваю ... как разделитель, когда он висит сам по себе вот так:

  • "Я подождал некоторое время... и затем я пошел домой"

Но опять же, может быть, я должен...

Мне также приходит в голову, что, возможно, лучший разделитель — это знак препинания, за которым следует пробел и заглавная буква:

string.split(/[?!.]\s+[A-Z]/).length
#=> 4
person pguardiario    schedule 08.09.2015
comment
Что, если есть мистер Юл, которому что-то нужно? - person Yule; 08.09.2015
comment
Вы можете объяснить это с помощью осмотра. Я оставлю это как упражнение для кого-то еще. - person pguardiario; 09.09.2015

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

txt = "The best things in an artist’s work are so much a matter of intuition, that there is much to be said for the point of view that would altogether discourage intellectual inquiry into artistic phenomena on the part of the artist. Intuitions are shy things and apt to disappear if looked into too closely. And there is undoubtedly a danger that too much knowledge and training may supplant the natural intuitive feeling of a student, leaving only a cold knowledge of the means of expression in its place. For the artist, if he has the right stuff in him ... "

sentence_count = txt.split(/\.|\?|!/).length
puts sentence_count
#=> 7
person Mourad    schedule 08.09.2015
comment
он создает несколько дополнительных пустых строк, для меня это 7. - person Rokibul Hasan; 08.09.2015
comment
Это из-за 3 полных остановок в конце. - person Mourad; 08.09.2015
comment
@Mourad Я отредактировал ваш ответ и заменил возвращаемое значение фактическим, то есть 7 - person Stefan; 08.09.2015