【问题标题】:Getting all possible consecutive 4 digit numbers from a 10 digit number从 10 位数字中获取所有可能的连续 4 位数字
【发布时间】:2017-09-14 08:22:36
【问题描述】:

我正在尝试制作一个正则表达式以从 10 位数字中获取所有可能的连续 4 位数字。喜欢

num = "2345678901";

输出: 2345345645675678678978908901

这些简单的正则表达式不起作用:

[\d]{4}
(\d\d\d\d)

【问题讨论】:

    标签: c# .net regex


    【解决方案1】:

    您需要使用(?=(\d{4})) 正则表达式来匹配重叠的匹配项。

    regex demo

    您使用的正则表达式都在消耗 4 位文本块,因此重叠值不匹配。使用(?=...) 正向前瞻,您可以测试输入字符串中的每个 位置,并从这些位置捕获 4 位块,而无需消耗字符(即不将正则表达式引擎指针移动到这 4 位数字块之后的位置)。

    C# demo:

    var data = "2345678901";
    var res = Regex.Matches(data, @"(?=(\d{4}))")
                .Cast<Match>()
                .Select(p => p.Groups[1].Value)
                .ToList();
    Console.WriteLine(string.Join("\n", res));
    

    【讨论】:

    • 这实际上与所需的结果不匹配,但匹配每个组合并将其放入该匹配的捕获组中......是的,它有效,我认为没有前瞻是不可能的,但我认为这是值得注意的。
    • @ThomasWeller: (?=...) 是一个积极的前瞻,一个零宽度的断言,一个让我们检查(或强制)某些字符存在的构造 after字符串中的当前位置。 Bikonja:我将我的结果与预期的结果进行了比较,它们是相同的。
    • @Koder101:正则表达式!= 正则表达式。它们有不同的种类。该问题不应同时标记为 .NET 和 Notepad++,因为这相互矛盾。
    • @Koder101 查看我的评论以获取答案。 Notepad++ 不知道(在查找中,仅在替换中)匹配中的捕获组,因此工作的 C# 代码,但不工作的 Notepad++ 正则表达式。我认为这在 Notepad++ 中是不可能的。
    • @Koder101:在 Notepad++ 中,使用 (?=(\d{4})) 并替换为 \nOVERLAPPED: $1\n。然后,用^OVERLAPPED:\h*\d{4}$ 正则表达式为重叠的行添加书签,将所有添加书签的行复制到一个新文件并删除“OVERLAPPED:”。这不是直截了当的,但有可能。
    【解决方案2】:

    您绝对需要使用正则表达式吗?使用简单的循环可以更快地完成相同的操作。

    private IEnumerable<string> getnums(string num)
    {
        for (int i = 0; i < num.Length - 3; i++)
        {
            yield return num.Substring(i, 4);
        }
    }
    
    private IEnumerable<string> DoIt(string num)
    {
        var res = Regex.Matches(num, @"(?=(\d{4}))")
                    .Cast<Match>()
                    .Select(p => p.Groups[1].Value)
                    .ToList();
        return (IEnumerable<string>)res;
    
    }
    

    平均而言,简单循环大约需要 RegEx 版本的一半时间。

    static void Main(string[] args)
    {
    
        var num = "2345678901";
    
        Stopwatch timer = new Stopwatch();
    
        timer.Start();
        foreach (var number in getnums(num))
        {
            // Yum yum numbers
        }
        timer.Stop();
        Console.WriteLine(timer.Elapsed.Ticks);
    
        timer.Reset();
    
        timer.Start();
        foreach (var number in DoIt(num))
        {
            // Yum yum numbers
        }
        timer.Stop();
        Console.WriteLine(timer.Elapsed.Ticks);
    }
    

    【讨论】:

    • 很好的比较,感谢您的方法。如果我回答你的问题,是的,有必要使用正则表达式。因为这个问题只是某些任务的一小部分,实际上我正在处理 - 1. 1000 位长的数字。 2. 实际要求是得到所有可能的 13 位数字,没有零。所以我修改后的正则表达式将是 - @"(?=([1-9]{13}))" 3. 然后用这些数字做一些任务。我选择使用 Regex 的原因是因为它提供的灵活性和关注点分离。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 1970-01-01
    • 2018-04-10
    • 1970-01-01
    相关资源
    最近更新 更多