2016-03-23 47 views
4

可能な限りすべての数字をの4桁の10桁の数字からなる正規表現にしようとしています。同様10桁の数字から連続する4桁の数字を取得する

num = "2345678901"; 

出力: 2345345645675678678978908901

これらの単純な正規表現が機能していない:

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

答えて

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; 

} 

単純なループは、正規表現のバージョンの約半分の時間を要します。

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

良い比較とあなたのアプローチのおかげで。あなたの質問に答えたら、はい、Regexを使う必要がありました。質問はちょっとした仕事の一部なので、実際には私は対処していた - 1. 1000桁の長い番号。 2.実際の要件は、ゼロを持たないすべての13桁の数字を取得することでした。だから私の修正Regexは - ** @ "(?=([1-9] {)})" ** 3.そしてそれらの番号でいくつかの仕事をしています。 Regexと一緒に行く理由は、それが提供する柔軟性と懸念の分離のためです。 – Koder101

関連する問題