1

「GSASearch」の合計「経過時間」を正規表現で計算したい。

私のログファイルの形式は次のとおりです。

WX Search = Server:nomos-scanner.corp.com User:vibsharm appGUID: wx Elapsed Time: 975ms SaveSearchID:361
WX Search = Server:nomos-scanner.corp.com User:vibsharm appGUID: wx Elapsed Time: 875ms SaveSearchID:361
GSA Search = Server:nomos-scanner.corp.com User:gulanand appGUID: wx Elapsed Time:890ms SaveSearchID:361
GSA Search = Server:nomos-scanner.corp.com User:vibsharm appGUID: wx Elapsed Time:887ms SaveSearchID:361
GSA Search = Server:nomos-scanner.corp.com User: gulanand appGUID: wx Elapsed Time: 875.5ms SaveSearchID:361
GSA Search = Server:nomos-scanner.corp.com User:vibsharm appGUID: wx Elapsed Time:877.6ms SaveSearchID:361

私のコード:

 string searchKeyword = "WX GSA Search";
            string fileName = @"C:\Users\karansha\Desktop\sample log.txt";
            string[] textLines = File.ReadAllLines(fileName);

            List<string> results = new List<string>();

            foreach (string line in textLines)
            {
                if (line.Contains(searchKeyword))
                {
                    results.Add(line);
                }
            }
            string x = string.Join(",", results);
            List<string> value = new List<string>();
            Regex regex = new Regex(@"Elapsed Time:\s*(?<value>\d+\.?\d*)\s*ms");
            MatchCollection matches = regex.Matches(x);
            foreach (Match match in matches)
            {
                var time = match.Groups["value"].Value;
                if (value.Contains(time)) value.Add(time);
            }
            int ElapsedTime = value.Count();
            Console.WriteLine(ElapsedTime);
            // keep screen from going away
            // when run from VS.NET
            Console.ReadLine();
4

4 に答える 4

3

Linqウェイ:

Regex regex = new Regex(@"Elapsed Time:\s*(?<value>\d+\.?\d*)\s*ms");
double totalTime = textLines.Where(line => line.Contains(searchKeyword))
                            .Select(line => regex.Match(line))
                            .Where(match => match.Captures.Count > 0)
                            .Sum(match => Double.Parse(match.Groups["value"].Value));

非Linqの方法:

Regex regex = new Regex(@"Elapsed Time:\s*(?<value>\d+\.?\d*)\s*ms");
double totalTime = 0;
int count = 0;
foreach (string line in textLines)
{
    if (line.Contains(searchKeyword))
    {
        Match match = regex.Match(line);
        if (match.Captures.Count > 0)
        {
            try
            {
                count++;
                double time = Double.Parse(match.Groups["value"].Value);
                totalTime += time;
            }
            catch (Exception)
            {
                // not a number
            }
        }
    }
}

double average = totalTime/count;
于 2013-03-04T10:57:21.693 に答える
2

正規表現なしでLINQを使用して合計時間を取得できます(ログファイルの形式が一貫しているため)。合計時間、平均時間、最大時間を計算するサンプルを次に示します(検索されたキーワードのログ項目がない場合、DefaultIfEmptyは0を返します)。

string searchKeyword = "GSA Search";
var times = File.ReadAllLines("log.txt")
                .Where(l => l.Contains(searchKeyword))
                .Select(ParseElapsedTime)
                .DefaultIfEmpty() 
                .ToList();

 var averageTime = times.Average();   // 882,525
 var maxTime = times.Max();           // 890
 var totalTime = times.Sum();         // 3530,1

ログラインからの経過時間を解析するには、別の方法を使用することをお勧めします。これにより、コードがより保守しやすくなります。

private static double ParseElapsedTime(string logLine)
{
    var startIndex = logLine.IndexOf("Elapsed Time:") + "Elapsed Time:".Length;
    var endIndex = logLine.IndexOf("ms", startIndex);
    var s = logLine.Substring(startIndex, endIndex - startIndex).Trim();
    return Double.Parse(s, CultureInfo.InvariantCulture.NumberFormat);
}

また、パフォーマンスが重要でない場合は、いつでも正規表現を使用して行を解析できます。メソッドの実装を変更するだけです。

于 2013-03-04T11:03:53.583 に答える
0

正規表現を使用してレコードあたりの経過時間をミリ秒単位で解析した場合、結果の文字列(例877.6)を浮動小数点値に変換できます。

string time = "234.4";
float elapsed = Single.Parse(time, CultureInfo.InvariantCulture);

Single.Parse値が有効な浮動小数点値であることが確実な場合にのみ使用してください。それ以外の場合は使用する必要がありますSingle.TryParseが、動作が少し異なります。

LINQを使用して、次のリストから経過時間を簡単に合計できますvalues

var values = new [] { "975", "875", "890", "887", "875.5", "877.6" };
float total = arr.Sum(v => Single.Parse(v, CultureInfo.InvariantCulture));
于 2013-03-04T10:58:22.590 に答える
0

これはVbにあります(ただし、c#に簡単に変換できます)。上記の文字列から、結果として5380.1が得られました。

Dim totaltime As Decimal = 0.0'choose your data type, I prefer decimal for accuracy
'This should get in between "Time:" and "ms" 
Dim getTimesRgx As New Regex("(?<=Time:)(.*?)(?=ms)", RegexOptions.IgnoreCase)
Dim Times As MatchCollection = getTimesRgx.Matches(YourFileAsString)
If Times.Count > 0 Then
   For Each time As Match In Times
      totaltime = totaltime + Decimal.parse(time.value)
   Next
End If
于 2013-03-11T18:22:03.230 に答える