Linq模式匹配 [英] Linq Pattern Matching

查看:106
本文介绍了Linq模式匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用正则表达式匹配模式,例如下面的示例,我正在匹配字符串以计算元音.

I am using Regular Expression for matching patterns say example in the follwoing example i am matching string to count vowels.

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#是否提供任何用于匹配模式的构造?

1) Without using regular expression does C# offer any construct for matching pattern?

2)为了针对字符串计算单个字符,我需要派生自己的方法吗?

2) For Counting individual character against the string do i need to derive my own method?

推荐答案

1)不使用正则表达式 C#是否提供任何构造 匹配模式?

1) Without using regular expression does C# offer any construct for matching pattern?

没有像正则表达式那么强大的功能可以一口气为您提供一切.

Nothing as powerful as regex that gives everything to you in one shot.

2)用于计算单个字符 我需要对字符串进行导出 我自己的方法?

2) For Counting individual character against the string do i need to derive my own method?

我不推荐这种方法 ,但我声明它只是为了表明您可以使用一些内置方法来实现它.您可以想象地使用 String.IndexOf 并查找以"a"开头的从0索引开始,并保持循环循环,同时在正匹配项上增加计数器.然后对"e" ..."u"重复,但是它比正则表达式或for循环的效率低得多.

I do not recommend this approach, but I'm stating it just to show that you could use some built in method to achieve it. You could conceivably use String.IndexOf and look for "a" starting from the 0 index, and keep chugging along in a loop while incrementing a counter on positive matches. Then repeat for "e"..."u" but it will be much less efficient than a regex or a for loop.

更好的方法是按字符逐个循环char,然后将其馈送到现有的switch语句或在某个集合中查找.

A better approach would be to just loop over the string char by char and either feed it to your existing switch statement or look it up in some collection.

由于您要使用LINQ,因此可以将上述for循环想法重写为适合的方式.请注意,这个想法类似于 HuBeZa的解决方案,因此在这里+1.但是,我使用列表进行查找,并使用StringComparison.InvariantCultureIgnoreCase枚举忽略大小写:

Since you want to use LINQ, here's how the above for loop idea could be rewritten to fit. Note, this idea is similar to HuBeZa's solution so +1 there. However, I use a list for the look up and use the StringComparison.InvariantCultureIgnoreCase enumeration to ignore case:

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);
}

我的原始正则表达式回复如下.

My original regex response is below.

正则表达式方法

有一个比您正在使用的正则表达式更好的解决方案.我不确定您是否知道它,因此我认为它值得发表.在第1个问题中,您说不使用正则表达式",但是恕我直言与第2个问题直接冲突,在第2个问题中,您询问是否必须派生自己的方法.

There's a better regex solution than the one you're using. I'm not sure if you're aware of it so I felt it warranted a post. In question #1 you said "without using regular expressions," but IMHO that directly conflicts with question #2 where you asked if you had to derive your own method.

您可以使用 Regex.Matches方法 Count属性:

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);
}

顺便说一句,您可以通过更改以下两项来进一步缩短原始代码:

BTW, you can further shorten your original code by changing 2 items:

1)字符串数组声明(在上面的示例中,我已经这样做了)
2)让您的案例陈述落入下一个案例标签:

1) The string array declaration (I've done this in my example above)
2) Make your case statements fall through to the next case label:

switch (c)
{
    case 'a':
    case 'e':
    case 'i':
    case 'o':
    case 'u':
        cnt++;
        break;
}

编辑:已使用LINQ查询进行了更新.只是使用Matches方法,这与OP的功能没有太大区别.

updated with a LINQ query. It's not much different than what the OP had, just using the Matches approach.

这篇关于Linq模式匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆