在javascript中将单词拆分为音节
Posted
技术标签:
【中文标题】在javascript中将单词拆分为音节【英文标题】:Splitting word into syllables in javascript 【发布时间】:2018-08-30 09:26:01 【问题描述】:我的目的是构建一个简单的过程,通过它我可以将单词分成音节。方法是在元音出现时拆分单词。但是,问题是当辅音后面没有元音时,在这种情况下会在该辅音处发生分裂。
我的测试用例如下:
hair = ["hair"]
hairai = ["hai", "rai"]
hatred = ["hat", "red"]
在第一个例子中,头发是一个音节,因为最后的辅音后面没有元音,同样,在最后一个例子中,“t”后面跟着一个 r,因此应该将“ha”视为一个音节. 在第二个例子中,ai 被认为是一个元音,所以 hai 将成为一个音节。
更多示例包括
father = ["fat", "her"]
kid = ["kid"]
lady = ["la","dy"]
请注意,我使用的是简单的例子,因为英语语言在声音方面非常复杂
我的代码如下
function syllabify(input)
var arrs = [];
for (var i in input)
var st = '';
var curr = input[i];
var nxt = input[i + 1];
if ((curr == 'a') || (curr == 'e') || (curr == 'i') || (curr == 'o') || (curr == 'u'))
st += curr;
else
if ((nxt == 'a') || (nxt == 'e') || (nxt == 'i') || (nxt == 'o') || (nxt == 'u'))
st += nxt;
else
arrs.push(st);
st = '';
console.log(arrs);
syllabify('hatred')
但是,我的代码甚至不返回字符串。我做错了什么?
【问题讨论】:
你在 for 循环中有var st = '';
。
我对你的例子有点困惑。你能解释一下你想要达到的目标吗?
你syllabificate的逻辑是什么?请先说明您的方法。
@gurvinder372 我怀疑这是问题之一,但逻辑也有偏差。因此要求澄清
描述father
和hatred
之间的区别。为什么一个 'fa'+'ther'
和另一个 'hat'+'red'
使用你的辅音元音方法
【参考方案1】:
您当前方法的问题
你的代码有很多问题:
循环中的第一件事,您将st
设置为一个空字符串。这意味着您永远不会积累任何信件。您可能想要上面的那一行,在循环之外。
您正在尝试使用i in input
循环遍历字母的索引。在 javascript 中,in
关键字将对象的键作为字符串提供给您。所以你得到的是字符串,而不是数字,以及在字符串上定义的一些方法的名称。请改用var i = 0; i < input.length; i++
。
也许不是问题的直接原因,但仍然 - 您的代码很混乱。这些怎么样?
使用更清晰的名称。 currentSyllable
代替 st
,syllables
代替 arrs
等等。
不要使用嵌套的if
- else
,而是使用一个if
- else if
- else
。
您重复检查元音两次的相同代码。而是将其拆分为函数isVowel(letter)
。
一种新方法
使用regular expressions!这是您对用正则表达式表示的音节的定义:
第一,零个或多个辅音:[^aeiouy]*
然后,一个或多个元音:[aeiouy]+
之后,零或以下之一:
辅音,后跟词尾:[^aeiouy]*$
辅音(如果后面跟着另一个辅音):[^aeiouy](?=[^aeiouy])
综合起来你得到这个:
/[^aeiouy]*[aeiouy]+(?:[^aeiouy]*$|[^aeiouy](?=[^aeiouy]))?/gi
您可以在here 中看到它。要在 JavaScript 中运行它,请使用 match
函数:
const syllableRegex = /[^aeiouy]*[aeiouy]+(?:[^aeiouy]*$|[^aeiouy](?=[^aeiouy]))?/gi;
function syllabify(words)
return words.match(syllableRegex);
console.log(['away', 'hair', 'halter', 'hairspray', 'father', 'lady', 'kid'].map(syllabify))
请注意,这不适用于没有元音的单词。您要么必须修改正则表达式以适应这种情况,要么做一些其他解决方法。
【讨论】:
希望您不介意,我更新了示例并使其更加健壮。真的很喜欢这种正则表达式方法,非常棒! 我还没有时间深入研究修复它(抱歉),但是这个正则表达式实现对于大多数事情来说可能很接近,但并不完全正确。 “火”(单音节)只是一个例子。我怀疑这与以元音结尾的单词有关? @DylanWatson 我尝试使用您在问题中概述的音节定义。但是我认为您不能仅根据辅音和元音来定义音节,您需要了解发音。 “火”和“婴儿”的辅音和元音相同,但一个有一个音节,另一个有两个。教计算机区分这些并非易事。【参考方案2】:我在 RegEx 方面很弱,虽然 Anders 的示例大部分时间都是正确的,但我确实发现了一些例外情况。这是我到目前为止发现的工作(但我确信还有其他我还没有发现的例外)。我相信艺术大师可以对其进行RegEx'ified。该函数返回一个音节数组。
function getSyllables(word)
var response = [];
var isSpecialCase = false;
var nums = (word.match(/[aeiou]/gi) || []).length;
//debugger;
if (isSpecialCase == false && (word.match(/[0123456789]/gi) || []).length == word.length )
// has digits
response.push(word);
isSpecialCase = true;
if (isSpecialCase == false && word.length < 4)
// three letters or less
response.push(word);
isSpecialCase = true;
if (isSpecialCase == false && word.charAt(word.length-1) == "e")
if (isVowel(word.charAt(word.length-2)) == false)
var cnt = (word.match(/[aeiou]/gi) || []).length;
if (cnt == 3)
if (hasDoubleVowels(word))
// words like "piece, fleece, grease"
response.push(word);
isSpecialCase = true;
if (cnt == 2)
// words like "phase, phrase, blaze, name",
if (hasRecurringConsonant(word) == false)
// but not like "syllable"
response.push(word);
isSpecialCase = true;
if (isSpecialCase == false)
const syllableRegex = /[^aeiouy]*[aeiouy]+(?:[^aeiouy]*$|[^aeiouy](?=[^aeiouy]))?/gi;
response = word.match(syllableRegex);
return response;
【讨论】:
ReferenceError: isVowel is not defined以上是关于在javascript中将单词拆分为音节的主要内容,如果未能解决你的问题,请参考以下文章
如何在 BigQuery SQL 中将字符串列拆分为多行单个单词和单词对?
如何在Python中将具有名称(1个或多个单词)和数字的单行输入字符串拆分为[“名称”,“数字”]?
华为OD机试真题Java实现相对开音节真题+解题思路+代码(2022&2023)