【问题标题】:If string contains 2 period in c#如果字符串在c#中包含2个句点
【发布时间】:2017-06-13 06:49:59
【问题描述】:

我正在尝试构建一个 Reg 表达式,如果文本框字符串在任何位置包含两个句点,它将执行我的代码。这是我到目前为止所得到的:

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

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

但是,它只在两个句点一起出现而不是字符串中的任何位置时执行...

【问题讨论】:

  • 你能给出一些有效和无效的示例字符串吗?必须正好是两个时期,不多不少?它们之间必须有空格吗?不具体就很难回答。
  • 为什么不直接使用textBoxSearch.Text.Count(c => c == '.') == 2
  • 根本不需要正则表达式。保持简单。
  • @L-Four 这取决于,他可能还想使用正则表达式替换或组捕获。
  • @Gusman,你的表情符合我的要求,谢谢。正如很多人建议的那样,我可能会尝试 LINQ。

标签: c# regex


【解决方案1】:

这里不需要正则表达式,使用 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

【讨论】:

  • "for 2 or more" 不是Count() &gt; 1 吗?
  • 这也可以,但使用SkipAny 会更快。这是因为Count 必须遍历整个IEnumerable,而Any 可以提前终止。
  • @sdgfsdh 是的,这是一个更简单的方法,谢谢!
  • @MickyD 如果性能真的很关键,最好使用简单的循环和计数器。
  • @MickyD 要计算 2 个 . 字符,循环就足够了。
【解决方案2】:

您应该声明两个句点以及它们周围和它们之间的句点以外的任何内容:

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

【讨论】:

    【解决方案3】:

    试试这个:

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

    如果 count == 2,则一切正常。

    【讨论】:

      【解决方案4】:

      这根据我的测试有效:

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

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

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

      【讨论】:

        【解决方案5】:

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

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

        【讨论】:

          【解决方案6】:

          一些人给出了测试 exactly 2 的示例,但这里有一个示例来测试 至少 2 个句点。如果您也愿意,您实际上可以轻松地修改它以测试正好 2。

           (.*\..*){2}
          

          【讨论】:

            猜你喜欢
            • 2020-04-07
            • 2015-11-08
            • 2011-12-24
            • 2014-05-07
            • 1970-01-01
            • 2023-03-14
            • 1970-01-01
            • 2011-05-14
            • 2021-07-24
            相关资源
            最近更新 更多