我正在使用正则表达式来匹配模式,请参阅以下示例中的示例我匹配字符串以计算元音。
void VowelsCountInEachWord()
{
Regex rx = new Regex("[aeiou]");
var words=new string[]
{"aesthetic", "benevolent", "abstract",
"capricious", "complacent", "conciliatory",
"devious", "diligent", "discernible","dogmatic",
"eccentric","fallacious","indifferent","inquisitive",
"meticulous","pertinent","plausible", "reticent"
};
var filter = from w in words where (rx.IsMatch(w.ToLower())) select new
{w,count=VowelsCounting(w)};
foreach (var v in filter)
{
Console.WriteLine("String {0} contains {1} vowels", v.w, v.count);
}
}
public int VowelsCounting(string value)
{
int cnt=0;
foreach (char c in value)
{
switch (c)
{
case 'a':cnt++;break;
case 'e':cnt++;break;
case 'i':cnt++;break;
case 'o':cnt++;break;
case 'u':cnt++;break;
}
}
return cnt++;
}
1)如果不使用正则表达式,C#是否提供匹配模式的任何构造?
2)对于字符串计算单个字符,我需要派生自己的方法吗?
答案 0 :(得分:3)
你的解决方案并不坏,但如果你坚持:
var vowels = new char[] { 'a', 'e', 'i', 'o', 'u' };
var words = new string[]
{"aesthetic", "benevolent", "abstract",
"capricious", "complacent", "conciliatory",
"devious", "diligent", "discernible","dogmatic",
"eccentric","fallacious","indifferent","inquisitive",
"meticulous","pertinent","plausible", "reticent"
};
var filter =
(from w in words
select new { w, count = w.ToLower().Count(c => vowels.Contains(c)) }).
Where(item => item.count > 0);
编辑:正如有人在这里建议的那样,我删除了ToCharArray,我添加了ToLower check&也是一个零元音滤波器。
答案 1 :(得分:3)
1)不使用正则表达式 C#是否提供任何构造 匹配模式?
没有像正则表达式那样强大的功能,可以一次性为你提供一切。
2)计算个人角色 反对字符串我需要派生 我自己的方法?
我不推荐这种方法 ,但我只是为了表明您可以使用一些内置方法来实现它。你可以想象使用String.IndexOf并从0索引开始寻找“a”,并在循环中继续前进,同时在正匹配上递增计数器。然后重复“e”......“u”但它的效率远低于正则表达式或for循环。
更好的方法是通过char循环遍历字符串char,并将其提供给现有的switch语句或在某些集合中查找。
由于您想使用LINQ,以下是如何重写上述for循环理念以适应。请注意,这个想法类似于HuBeZa's solution所以+1那里。但是,我使用列表进行查找并使用StringComparison.InvariantCultureIgnoreCase
枚举来忽略大小写:
var vowels = new List<string> { "a", "e", "i", "o", "u" };
var query = words.Select(s => new
{
Text = s,
Count = s.Count(c => vowels.Exists(vowel =>
vowel.Equals(c.ToString(),
StringComparison.InvariantCultureIgnoreCase)))
});
foreach (var item in query)
{
Console.WriteLine("String {0} contains {1} vowels", item.Text, item.Count);
}
我原来的正则表达式响应如下。
正则表达式方法
有一个比你正在使用的更好的正则表达式解决方案。我不确定你是否意识到这一点,所以我认为这是一个帖子。在问题#1中,你说“不使用正则表达式”,但恕我直言,问题是你问你是否必须推导出自己的方法。问题#2
您可以使用返回的MatchCollection上的Regex.Matches method和Count property来缩短代码:
Regex rx = new Regex("[aeiou]");
// to ignore case use: new Regex("[aeiou]", RegexOptions.IgnoreCase);
string[] words =
{
"aesthetic", "benevolent", "abstract",
"capricious", "complacent", "conciliatory",
"devious", "diligent", "discernible","dogmatic",
"eccentric","fallacious","indifferent","inquisitive",
"meticulous","pertinent","plausible", "reticent"
};
foreach (string input in words)
{
Console.WriteLine("String {0} contains {1} vowels",
input, rx.Matches(input).Count);
}
// if you really want to use LINQ
var query = from s in words
select new
{
Text = s,
Count = rx.Matches(s).Count
};
foreach (var item in query)
{
Console.WriteLine("String {0} contains {1} vowels", item.Text, item.Count);
}
顺便说一句,您可以通过更改2项来进一步缩短原始代码:
1)字符串数组声明(我在上面的例子中完成了这个)
2)让你的案例陈述落到下一个案例标签:
switch (c)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
cnt++;
break;
}
使用LINQ查询更新编辑。它与OP的差别不大,只是使用匹配方法。
答案 2 :(得分:2)
以下解决方案仅包含项目,如果它包含元音,并且它将是最快的解决方案。
var filter = from w2 in
(from w in words
select new
{
w,
count =
w.ToLower().ToCharArray().Count(
c => c == 'a' ||
c == 'e' ||
c == 'i' ||
c == 'o' ||
c == 'u')
})
where (w2.count > 0)
select w2;
答案 3 :(得分:1)
每个人都让这太复杂了:
Regex rx = new Regex("[aeiou]", RegexOptions.IgnoreCase);
var query = from w in words
let vowelCount = rx.Matches(w).Count
where vowelCount != 0
select new { w, vowelCount };
当然如果你不需要一个有元音的单词列表(什么单词没有?)而你想要做的就是输出计数,那么就更容易使用一个循环。