我在这里使用了迪伦问题,用于JavaScript音节计数,更确切地说,是艺术黑客的回答,在我自己的代码中,不管我输入哪个单词字符串,函数总是能够正确地计算音节数。
我对RegEx的经验有限,没有足够的先验知识,无法在没有帮助的情况下破译下面的代码中到底发生了什么。我不是一个喜欢从某个地方提取代码的人,只是在我不知道它是如何工作的情况下就开始工作了。有人能请你说出下面的new_count(word)函数中发生了什么,并帮助我破译RegEx的使用,以及函数如何能够正确地计算音节吗?许多
function new_count(word) {
word = word.toLowerCase(); //word.downcase!
if(word.length <= 3) { return 1; } //return 1 if word.length <= 3
word = word.replace(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, ''); //word.sub!(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, '')
word = word.replace(/^y/, ''); //word.sub!(/^y/, '')
return word.match(/[aeiouy]{1,2}/g).length; //word.scan(/[aeiouy]{1,2}/).size
}发布于 2015-02-07 17:43:35
据我所见,我们基本上想计算元音,或元音对,有一些特殊情况。让我们从最后一行开始,也就是数元音和对:
return word.match(/[aeiouy]{1,2}/g).length;这将匹配任何元音,或元音对。[...]的意思是一个字符类,也就是说,如果我们逐个字符遍历字符串,我们就有一个匹配,如果实际的字符是其中之一。{1, 2}是重复的数目,也就是说我们应该匹配一个或两个这样的字符。
另外两行是特例。
word = word.replace(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, '');这一行将从单词的末尾删除‘音节’,其中之一是:
(我不太清楚这句话背后的语法含义是什么,但我想,这个词末尾的“音节”,比如“-ed”、“-ed”、“-such”等等,其实都不算。)至于regexp部分:(?:...)是一个非捕获群。我想在这种情况下,不捕获这个组并不重要;这只是意味着我们想对整个表达式进行分组,但是我们不需要再引用它。但是,我们也可以使用捕获组(即(...) )。
[^...]是一个否定的字符类。它的意思是,匹配任何字符,这不是在这里列出的。(与上述(非否定的)字符类相比。)管道符号,即|,是交替操作符,这意味着任何表达式都可以匹配。最后,$锚点匹配终点线或字符串(取决于上下文)。
word = word.replace(/^y/, '');这一行删除单词开头的'y'-s (可能开头的'y‘不算作音节--这在我看来是有道理的)。^是匹配线的开头或string (c.f )的锚点。(上述$ )。
注意:只有当word真正包含一个单词时,该算法才能工作。
发布于 2015-02-07 17:30:47
/(?:[^laeiouy]es|ed|[^laeiouy]e)$/它与三种可能的子字相匹配:字母'l‘或元音后面跟着'es’(如"res“或"tes");'ed';或一个非元音,非‘l’,后面只有'e‘。由于模式末尾的$,这些模式必须出现在单词的末尾才能匹配。分组(?: )只是一个分组;领先的?:做出了这种区分。这一模式本可以稍微短一点:
/(?:[^laeiouy]es?|ed)$/也会做同样的事。在任何情况下,如果模式匹配,所涉及的字符将从单词中删除。
然后,
/^y/与单词开头的“y”匹配。如果找到“y”,它就会被移除。
最后,
/[aeiouy]{1,2}/g匹配任何一个或两个字符的元音段(包括'y')。g后缀使其成为一个全局匹配,因此返回值是由所有这类元音范围组成的数组。返回数组的长度是音节数(根据这项技术)。
请注意,单词“诗”和“狮子”将报告为一个音节的词,这可能是正确的一些英语变体,但不是所有。
https://stackoverflow.com/questions/28384718
复制相似问题