我想知道是否有办法检查字符串是否包含任何关键字是列表,如果找到则返回找到的关键字。
例如,我有一个keywords
列表。
List<string> keywords = new List<string>{"word1", "word2", "word3"};
我有sentence
(字符串)我想检查关键字:
string sentence = "something something something word2 something something";
有没有办法搜索keywords
中的sentence
并返回找到的?{1}}?例如,返回word2
。
我知道我可能只是使用forloop循环关键字,但由于我的实际程序中至少有20个关键字,我不想这样做,因为它使我的代码有点混乱。
我最初的想法是这样的:
string SearchKeywords(List<string> keywords, string sentence){
foreach (string word in keywords){
if (sentence.Contains(word)) return word;
}
return ""; //return blank string if no match found
}
我想知道是否有可用于完成工作的内置功能。谢谢!
答案 0 :(得分:3)
您可以使用Linq的FirstOrDefault
扩展方法:
string SearchKeywords(List<string> keywords, string sentence){
return keywords.FirstOrDefault(w => sentence.Contains(w)) ?? "";
}
最后的?? ""
只是意味着如果在字符串中找不到关键字,那么你的方法应该返回一个空字符串。
答案 1 :(得分:3)
使用正则表达式,您可以使用关键字创建替换,以获得word1|word2|word3
的模式。它们应该通过Regex.Escape
进行转义,以避免与任何正则表达式元字符冲突。忽略大小写是通过添加RegexOptions.IgnoreCase
选项完成的。
string pattern = String.Join("|", keywords.Select(k => Regex.Escape(k)));
Match m = Regex.Match(sentence, pattern, RegexOptions.IgnoreCase);
if (m.Success)
{
Console.WriteLine("Keyword found: {0}", m.Value);
}
else
{
Console.WriteLine("No keywords found!");
}
如果您改变主意并希望找到多个匹配项,请改用Regex.Matches
并循环显示结果。
答案 2 :(得分:0)
如果您知道每个句子只能得到一个单词(并且您确定您一次只检查一个句子),我会使用pswg&#39的答案。对于一个类似的将查看更长的字符串(因此可能返回多个结果),只需使用.Where()
,如下所示:
IEnumerable<string> SearchKeywords(List<string> keywords, string sentence)
{
return keywords.Where(w => sentence.ToLower().Contains(w.ToLower()));
}
在这种情况下,您不需要null
合并运算符(??
)因为Enumerable将以任何方式返回,如果没有任何匹配,那么它将返回一个没有元素的Enumerable。
请注意,这会找到部分字匹配(例如,关键字&#34; cray&#34;将匹配句子字&#34;蜡笔。&#34;您可以通过在关键字周围添加空格来解决此问题(因此:&#34; cray&#34;),或者将你的句子分成带有.Split()
的数组并检查两个Enumerables:
IEnumerable<string> SearchKeywords(List<string> keywords, string sentence)
{
var splitSentence = sentence.ToLower().Split(' ');
return keywords.Intersect(splitSentence);
}