从10位数字中获取所有可能的连续4位数字

时间:2016-03-23 20:36:37

标签: c# .net regex

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

num = "2345678901";

输出 2345345645675678678978908901

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

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

2 个答案:

答案 0 :(得分:7)

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

请参阅regex demo

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

enter image description here

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

答案 1 :(得分: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);
}