我有一个.NET应用程序,在其中给定了一个名词,我希望它为该单词加上“ a”或“ an”前缀。我该怎么做?
在您认为答案只是简单地检查第一个字母是否是元音之前,请考虑以下短语:
- 一个诚实的错误
- 二手车
我有一个.NET应用程序,在其中给定了一个名词,我希望它为该单词加上“ a”或“ an”前缀。我该怎么做?
在您认为答案只是简单地检查第一个字母是否是元音之前,请考虑以下短语:
Answers:
您可能没有比这更好的了-它肯定会击败大多数基于规则的系统。
编辑:我已经在JS / C#中实现了这一点。您可以在浏览器中进行尝试,或下载其使用的小型可重复使用的javascript实现。.NET实现是AvsAn
在nuget上打包的。这些实现是微不足道的,因此在必要时应易于移植到任何其他语言。
原来,“规则”比我想象的要复杂得多:
...这恰恰说明基于规则的系统构建起来很棘手!
您需要使用例外列表。我认为并非所有例外都定义明确,因为有时这取决于说这个单词的人的口音。
一种愚蠢的方法是要求Google提供两种可能性(使用一种搜索API)并使用最受欢迎的一种:
要么:
因此,“欧洲”和“诚实”是正确的版本。
如果您可以找到单词发音的单词拼写来源,例如:
"honest":"on-ist"
"horrible":"hawr-uh-buhl, hor-"
您可以根据拼写发音字符串的第一个字符来做出决定。为了提高性能,也许您可以使用这种查找来预先生成异常集,并在执行期间使用那些较小的查找集。
编辑添加:
!!! -我认为您可以使用它来生成异常:http : //www.speech.cs.cmu.edu/cgi-bin/cmudict
当然,并不是所有的东西都在字典中-这意味着并不是所有可能的异常都会出现在您的异常集中-但是在这种情况下,您可以默认为元音为a /辅音为a或使用其他具有更好几率的启发式方法。
(通过查看CMU词典,我很高兴看到它包含了国家和其他地方的专有名词-因此它将提供“乌克兰语”,“今日美国报”,“乌拉尔风格的绘画”等示例。)
再次编辑以添加:CMU词典不包含常见的缩写词,您必须担心那些以s,f,l,m,n,u和x开头的缩写词。但是,有很多首字母缩写词列表,例如Wikipedia中的缩写词,您可以使用它来添加例外。
hawr-uh-buhl
总是让我发笑。
您必须手动实现并添加所需的异常,例如,如果第一个字母为“ H”,后跟“ O”(例如诚实,小时...)以及相反的字符(例如欧洲,大学),则使用...
由于“ a”和“ an”是由语音规则而不是拼写约定确定的,所以我可能会这样做:
您需要查看不定冠词的语法规则(英语语法中只有两个不定冠词-“ a”和“ an”。您可能不同意这些听起来正确,但是英语语法的规则非常明确:
“ a和an是不定冠词。我们使用不定冠词a以元音开头(a,e,i,o,u),而不定冠词a以辅音开头(所有其他字母)。”
注意,这意味着一个元音的声音,而不是一个元音字母。例如,以无声的“ h”开头的单词(例如“ honour”或“ heir”)被视为元音,因此以“ an”开头-例如,“很高兴认识您”。以辅音开头的单词以-开头,这就是为什么您说“二手车”而不是“二手车”的原因-因为“二手”的声音是“洋洋”而不是“呃”。
因此,作为程序员,这些是要遵循的规则。您只需要确定一种方法即可确定单词的发音,而不是字母。我已经看到了这样的示例,例如Jaimie Sirovich 在PHP中撰写的示例:
function aOrAn($next_word)
{
$_an = array('hour', 'honest', 'heir', 'heirloom');
$_a = array('use', 'useless', 'user');
$_vowels = array('a','e','i','o','u');
$_endings = array('ly', 'ness', 'less', 'lessly', 'ing', 'ally', 'ially');
$_endings_regex = implode('|', $_endings);
$tmp = preg_match('#(.*?)(-| |$)#', $next_word, $captures);
$the_word = trim($captures[1]);
//$the_word = Format::trimString(Utils::pregGet('#(.*?)(-| |$)#', $next_word, 1));
$_an_regex = implode('|', $_an);
if (preg_match("#($_an_regex)($_endings_regex)#i", $the_word)) {
return 'an';
}
$_a_regex = implode('|', $_a);
if (preg_match("#($_a_regex)($_endings_regex)#i", $the_word)) {
return 'a';
}
if (in_array(strtolower($the_word{0}), $_vowels)) {
return 'an';
}
return 'a';
}
创建规则然后创建例外列表并使用它可能是最简单的。我不认为会有那么多。
伙计,我意识到这可能是一个确定的论点,但我认为它比使用Wikipedia的即席语法规则充其量要容易得多,后者最多只能得出白话语法。
最好的解决方案似乎是使用a或触发器来实现后续单词的基于音素的匹配,其中某些音素始终与“ an”相关联,而其余音素则与“ a”相关。
卡内基梅隆大学拥有一个出色的在线工具,可以进行此类检查-http : //www.speech.cs.cmu.edu/cgi-bin/cmudict-并以125k的单词数和39个音素相匹配。插入单词会提供整个语音组,其中只有第一个很重要。
如果单词未出现在字典中,例如“ NSA”,并且全部大写,则系统可以假定该单词为首字母缩写词,并根据相同的原始规则集使用第一个字母来确定要使用哪个不定冠词。
@Nathan Long:下载维基百科实际上不是一个坏主意。不需要所有图像,视频和其他媒体。
我用php和javascript(!)编写了一个(糟糕的)程序,以阅读整个瑞典语维基百科(或至少从有关数学的文集中可以找到的所有小书,这就是我的蜘蛛的开始。)
我在数据库中收集了所有单词和内部链接,并跟踪了每个单词的出现频率。现在,我将其用作单词数据库来执行各种任务:*查找可以从给定字母集(包括通配符)创建的所有单词*为瑞典语创建了简单的语法文件(所有不在数据库中的单词均被视为不正确)。
哦,使用我的笔记本电脑大部分时间都是在10Mbit的连接下运行的,下载整个Wiki大约花了一个星期的时间。
当您使用它时,请记录所有与英语不一致的情况,并查看其中是否有错误。修复它们并回馈社区。
请注意,正如“语法女孩”在她的情节A对战方言中指出的那样,美国和英国方言之间存在差异。
一种复杂的情况是,英语和美式英语中的单词发音不同。例如,某种植物的单词在美式英语中发音为“ erb”,在英式英语中发音为“ herb”。在极少数情况下这是一个问题,请使用您所在国家或大多数读者所期望的表格。
我不认为您可以一步一步地填写一些“ a / an”样板文件。否则,您将遇到假设错误,例如所有带有“ h”的单词都以“ o”开头,而不是像“ home”之类的“ a”(家庭)?基本上,您最终会包括英语的逻辑,或者偶尔发现使您看起来很愚蠢的罕见情况。
规则很简单。如果下一个单词以元音开头,则使用“ an”;如果下一个单词以辅音开头,则使用“ a”。困难的是,我们在学校对元音和辅音的分类不起作用。“荣誉”中的“ h”是元音,但“医院”中的“ h”是辅音。
更糟糕的是,诸如“诚实”之类的词以元音或辅音开头,取决于谁在说。更糟糕的是,某些说话者会根据周围的单词改变某些单词。
问题仅取决于您要投入多少时间和精力。您可以在几分钟之内使用“ aeiou”作为元音在一对夫妇中写一些东西,或者您可以花费数月的时间对目标受众进行语言分析。它们之间有大量的启发式方法,对于某些说话者来说是正确的,而对于另一些说话者来说则是错误的-但是由于不同的说话者对同一个单词有不同的判断力,因此无论您怎么做,都不可能一直都是正确的它。
只要下一个单词不是元音,就使用“ a”吗?当有元音时,您使用“ an”吗?
这么说,您难道不就做一个正则表达式,例如“ a \ s [a,e,i,o,u]。*”吗?然后将其替换为“ an”?