2016-03-23 37 views

回答

7

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

见您使用的全部消耗文本的4个数据块的regex demo

的正则表达式,因此,重叠的值不匹配。与(?=...)正超前,可以测试输入字符串内的每个位置,并且捕获从这些位置 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)); 
+0

现在我们知道它的工作原理是什么?=是什么意思? –

+0

啊!感谢更新。 –

+0

这实际上并不符合想要的结果,但匹配每个组合并将其放入捕获组以匹配该匹配...是的,它可以工作,并且我认为没有预见,这是可能的,但这是值得注意的认为。 – Bikonja

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.然后用这些数字做一些任务。 我选择使用正则表达式的原因是它提供的灵活性和关注点的分离。 – Koder101