2017-01-27 3 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

Это работает по моим тестам:

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

Любой символ ноль или более раз, за ​​которым следует период, за которым следует любой символ, ноль или более раз, за ​​которым следует период, за которым следует любой символ, ноль или более раз.

Конечно, как указывали другие, использование Regex здесь не самый эффективный или читаемый способ его выполнения. У Regex есть кривая обучения, и будущие программисты могут не оценить менее простой подход, учитывая, что существуют более простые альтернативы.

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} 
Смежные вопросы