如何使用.Contains()方法从句子中提取关键词匹配USerLanguage列表中的记录
如何从自然语言句子中提取语言关键词并匹配对应记录?
你的问题核心是匹配逻辑搞反啦!原来的代码是检查LanguageName是否包含整个问题字符串,但你实际需要的是检查问题字符串里是否包含LanguageName中的核心语言关键词。下面给你两种实用的实现方式:
方法一:提取语言名称核心词,反向匹配
这种方式直接从LanguageName中提取出不带地区后缀的核心语言名(比如从French (France)拿到French),然后检查问题字符串里是否包含这个核心词:
var question = "change language to french"; var allLanguage = new List<USerLanguage>() { new USerLanguage(){LanguageName="English (United States)", LanguageCode="en-US"}, new USerLanguage(){LanguageName="German (Germany)",LanguageCode="de-DE"}, new USerLanguage(){LanguageName="French (France)", LanguageCode="fr-FR"}, }; var targetLanguage = allLanguage.Where(r => { // 提取核心语言名称:拆分括号前的部分并去除空格 var coreLanguage = r.LanguageName.Split('(')[0].Trim().ToLower(); // 检查问题字符串(转小写后)是否包含核心语言词 return question.ToLower().Contains(coreLanguage); }).ToList();
这个方法简单直接,完全适配你当前的USerLanguage数据结构,能精准匹配到句子中的语言关键词。
方法二:基于单词集合的灵活匹配
如果之后需要支持更复杂的场景(比如问题里有缩写、多语言变体),可以把问题和语言名称都拆成单词集合,然后检查是否有重叠的单词:
var question = "change language to french"; var allLanguage = new List<USerLanguage>() { new USerLanguage(){LanguageName="English (United States)", LanguageCode="en-US"}, new USerLanguage(){LanguageName="German (Germany)",LanguageCode="de-DE"}, new USerLanguage(){LanguageName="French (France)", LanguageCode="fr-FR"}, }; // 把问题拆成单词集合(忽略大小写和标点) var questionWords = new HashSet<string>( question.ToLower().Split(new[] {' ', '(', ')', '.', ','}, StringSplitOptions.RemoveEmptyEntries) ); var targetLanguage = allLanguage.Where(r => { // 把语言名称拆成单词集合 var languageWords = r.LanguageName.ToLower().Split(new[] {' ', '(', ')'}, StringSplitOptions.RemoveEmptyEntries); // 检查是否有重叠的单词 return languageWords.Any(word => questionWords.Contains(word)); }).ToList();
这种方式容错性更强,比如如果问题是"switch to fr",只要LanguageName里有fr相关的单词,也能匹配到。
为什么原来的代码不生效?
你原来的代码是r.LanguageName.ToLower().Contains(question),这相当于要求French (France)转小写后要包含整个句子"change language to french",显然这是不可能的——反过来检查问题里是否包含语言关键词,才是正确的逻辑方向。
内容的提问来源于stack exchange,提问作者Mr. Das
相关产品推荐
相关产品推荐

