2017-01-27 48 views
1

我想建立一个Reg表达式,其中如果文本框字符串包含两个句点,它将执行我的代码。这是我到目前为止有:如果字符串包含2个句点在c#

Regex word = new Regex("(\\.){2,}"); 

if (word.IsMatch(textBoxSearch.Text)) 
{ 
    //my code here to execute 
} 

但是,如果有两个时期在一起,并在字符串中没有在任何地方,只执行...

+1

你可以给一些有效和无效的例子字符串吗?它必须是两个阶段,不多不少?他们之间有空间吗?没有你的具体情况很难回答。 – Equalsk

+0

'“。*?\\ .. *?\\。” – Gusman

+0

为什么不使用'textBoxSearch.Text.Count(c => c =='。')== 2'? – stuartd

回答

9

没有必要对正则表达式在这里,只需使用LINQ!

myString.Count(x => x == '.') == 2 

或为2个或更多

myString.Where(x => x == '.').Skip(1).Any() 

如果性能是至关重要的,你应该使用一个循环。下面是三种方法(LINQ,循环,正则表达式)的比较:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text.RegularExpressions; 

namespace Experiment 
{ 
    public static class Program 
    { 
     static bool hasTwoPeriodsLinq(string text) 
     { 
      return text.Count(x => x == '.') == 2; 
     } 

     static bool hasTwoPeriodsLoop(string text) 
     { 
      int count = 0; 

      for (int i = 0; i < text.Length; i++) 
      { 
       if (text[i] == '.') 
       { 
        // This early break makes the loop faster than regex 
        if (count == 2) 
        { 
         return false; 
        } 

        count++; 
       } 
      } 

      return count == 2; 
     } 

     static Regex twoPeriodsRegex = new Regex(@"^.*\..*\..*$", RegexOptions.Compiled); 

     static bool hasTwoPeriodsRegex(string text) 
     { 
      return twoPeriodsRegex.IsMatch(text); 
     } 

     public static void Main(string[] args) 
     { 
      var text = @"The young Princess Bolk6nskaya had 
brought some work in a gold-embroidered vel- 
vet bag. Her pretty little upper lip, on which 
a delicate dark down was just perceptible, was 
too short for her teeth, but it lifted all the more 
sweetly, and was especially charming when she 
occasionally drew it down to meet the lower 
lip. As is always the case with a thoroughly at- 
tractive woman, her defectthe shortness of 
her upperlip and her half-open mouth seemed 
to be her own special and peculiar form of 
beauty. Everyone brightened at the sight of 
this pretty young woman, so soon to become 
a mother, so full of life and health, and carry- 
ing her burden so lightly. Old men and dull 
dispirited young ones who looked at her, after 
being in her company and talking to her a 
litttle while, felt as if they too were becoming, 
like her, full of life and health. All who talked 
to her, and at each word saw her bright smile 
and the constant gleam of her white teeth, 
thought that they were in a specially amiable 
mood that day. "; 

      const int iterations = 100000; 

      // Warm up... 
      for (int i = 0; i < iterations; i++) 
      { 
       hasTwoPeriodsLinq(text); 
       hasTwoPeriodsLoop(text); 
       hasTwoPeriodsRegex(text); 
      } 

      var watch = System.Diagnostics.Stopwatch.StartNew(); 

      // hasTwoPeriodsLinq 
      watch.Restart(); 

      for (int i = 0; i < iterations; i++) 
      { 
       hasTwoPeriodsLinq(text); 
      } 

      watch.Stop(); 

      Console.WriteLine("hasTwoPeriodsLinq " + watch.ElapsedMilliseconds); 

      // hasTwoPeriodsLoop 
      watch.Restart(); 

      for (int i = 0; i < iterations; i++) 
      { 
       hasTwoPeriodsLoop(text); 
      } 

      watch.Stop(); 

      Console.WriteLine("hasTwoPeriodsLoop " + watch.ElapsedMilliseconds); 

      // hasTwoPeriodsRegex 
      watch.Restart(); 

      for (int i = 0; i < iterations; i++) 
      { 
       hasTwoPeriodsRegex(text); 
      } 

      watch.Stop(); 

      Console.WriteLine("hasTwoPeriodsRegex " + watch.ElapsedMilliseconds); 
     } 
    } 
} 

试试吧here

而且结果:

hasTwoPeriodsLinq 1280

hasTwoPeriodsLoop 54

hasTwoPeriodsRegex 74

+2

“2个或更多”不是“Count()> 1”吗? –

+0

这也可以,但使用'Skip'和'Any'会更快。这是因为'Count'必须遍历整个'IEnumerable',而'Any'可以提前终止。 – sdgfsdh

+0

@sdgfsdh是的,这是一个更简单的方法,谢谢! – Rickshaw

2

这根据我的测试工作:

^.*\..*\..*$ 

任何字符零次或多次,后跟一个句点,后跟任意字符零次或多次,后跟一个句点,后跟任意字符零次或多次。

当然,正如其他人指出的,在这里使用正则表达式并不是最有效或可读的方式。正则表达式有一个学习曲线,考虑到有更简单的替代方法,未来的程序员可能不会赞赏不太直截了当的方法。

4

你应该申报唯独身边期两个时期和任何东西,它们之间:

[^\.]*\.[^\.]*\.[^\.]* 
3

试试这个:

int count = source.Count(f => f == '.'); 

如果count == 2,你都很好。

2

如果你想使用正则表达式,那么你可以使用Regex.Matches来检查计数。

if(Regex.Matches(stringinput, @"\.").Count == 2) 
{ 
//perform your operation 
} 
2

有几个人给出的例子来测试正是 2,但这里有一个例子来测试至少 2个周期。如果你也想,也可以很容易地修改它以测试2。

(.*\..*){2}