我用过Dylan's question在这里关于 JavaScript 音节计数,更具体地说 artfulhacker's answer ,在我自己的代码中,无论我输入哪个单字串或多字串,该函数始终能够正确计算音节数。
我对 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
}
最佳答案
据我所知,我们基本上是想计算元音或元音对,但有一些特殊情况。让我们从最后一行开始,即计算元音和元音对:
return word.match(/[aeiouy]{1,2}/g).length;
这将匹配任何元音或元音对。 [...]
表示 character class ,即如果我们逐个字符地遍历字符串,如果实际字符是其中之一,我们就会匹配。 {1, 2}
是 repetitions 的个数,即这意味着我们应该恰好匹配一个或两个这样的字符。
另外两行用于特殊情况。
word = word.replace(/(?:[^laeiouy]es|ed|[^laeiouy]e)$/, '');
此行将从单词末尾删除“音节”,它们是:
- Xes(其中 X 不是任何“laeiouy”,例如“zes”)
- ed
- Xe(其中 X 不是任何“laeiouy”,例如“xe”)
(我不太确定这背后的语法含义是什么,但我猜,单词末尾的“音节”,如“-ed”、“-ded”、“-xed” ' 等。实际上不算在内。)
至于正则表达式部分:(?:...)
是 non-capturing group .我想在这种情况下,这个组是否非捕获并不重要;这只是意味着我们想对整个表达式进行分组,但是我们不需要回头引用它。但是,我们也可以使用捕获组(即 (...)
)
[^...]
是一个否定字符类。它的意思是,匹配任何字符,这里没有列出这些字符。 (与上面提到的(非否定的)字符类相比。)
管道符号,即 |
,是 alternation运算符,这意味着任何表达式都可以匹配。
最后,$
anchor 匹配 end of the line , 或字符串(取决于上下文)。
word = word.replace(/^y/, '');
这一行从单词的开头删除了“y”-s(开头的“y”可能不算作音节——我认为这是有道理的)。
^
是匹配 the beginning of the line 的 anchor , 或字符串(参见上面提到的 $
)。
注意:该算法仅在 word
确实包含一个单词时有效。
关于javascript - 正则表达式:了解音节计数器代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28384718/