Ruby,Count音节

我正在使用ruby计算一些内容的Gunning Fog Index,我可以成功实现这里描述的算法:

Gunning雾指数

我使用以下方法来计算每个单词中的音节数:

Tokenizer = /([aeiouy]{1,3})/ def count_syllables(word) len = 0 if word[-3..-1] == 'ing' then len += 1 word = word[0...-3] end got = word.scan(Tokenizer) len += got.size() if got.size() > 1 and got[-1] == ['e'] and word[-1].chr() == 'e' and word[-2].chr() != 'l' then len -= 1 end return len end 

它有时只用2个音节来获取有3个音节的单词。 任何人都可以提出任何建议或者知道更好的方法吗?

 text = "The word logorrhoea is often used pejoratively to describe prose that is highly abstract and contains little concrete language. Since abstract writing is hard to visualize, it often seems as though it makes no sense and all the words are excessive. Writers in academic fields that concern themselves mostly with the abstract, such as philosophy and especially postmodernism, often fail to include extensive concrete examples of their ideas, and so a superficial examination of their work might lead one to believe that it is all nonsense." # used to get rid of any puncuation text = text.gsub!(/\W+/, ' ') word_array = text.split(' ') word_array.each do |word| puts word if count_syllables(word) > 2 end 

“他们自己”被算作3,但它只有2

我之前给你的function是基于这里概述的这些简单规则:

单词中的每个元音(a,e,i,o,u,y)都算作一个音节,受以下子规则的约束:

  • 忽略最后的-ES,-ED,-E(-LE除外)
  • 三个字母或更少的字数统计为一个音节
  • 连续元音计为一个音节。

这是代码:

 def new_count(word) word.downcase! return 1 if word.length <= 3 word.sub!(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, '') word.sub!(/^y/, '') word.scan(/[aeiouy]{1,2}/).size end 

显然,这也不是完美的,但你所能得到的东西都是启发式的。

编辑:

我稍微更改了代码以处理前导'y'并修复了正则表达式以更好地处理'les'结尾(例如在“蜡烛”中)。

以下是使用问题中的文字进行的比较:

 # used to get rid of any puncuation text = text.gsub!(/\W+/, ' ') words = text.split(' ') words.each do |word| old = count_syllables(word.dup) new = new_count(word.dup) puts "#{word}: \t#{old}\t#{new}" if old != new end 

输出是:

 logorrhoea: 3 4 used: 2 1 makes: 2 1 themselves: 3 2 

所以它似乎是一种进步。

你应该做的一件事是教你的算法关于双元音 。 如果我正确地阅读你的代码,它会错误地将“援助”标记为有两个音节。

您还可以将“es”等添加到您的特殊情况结​​尾(您已经拥有“ing”)并且不将其视为音节,但这可能仍会导致一些错误计数。

最后,为了获得最佳准确度,您应该将输入转换为与单词的发音有明确关系的拼写方案或字母表。 使用您的“自己”示例,该算法没有可靠的方法来知道“e”“ves”被删除。 但是,如果你把它作为“themselvz”重新驱逐,或者教了算法IPA并喂它[ðəmsɛlvz],很明显这个词只用两个音节发音。 当然,这假设您可以控制输入,并且可能更多的工作不仅仅是自己计算音节。

首先,你似乎应该减去len应该被排除的后缀。

 len-=1 if /.*[ing,es,ed]$/.match(word) 

您还可以查看Lingua :: EN :: Readability 。

它还可以计算几种可读性度量,例如雾指数和Flesch-Kincaid级别。

PS。 我想我知道你从哪里获得这个function。 DS。

还有一个名为Odyssey的rubygem可以计算出Gunning Fog以及其他一些受欢迎的(Flesch-Kincaid,SMOG等)。