-1

これは厄介なことです。Beyond Compare スクリプト レポートからのテキスト ブロックがありました。

Picture Compare
Produced: 10/17/2012 9:42:25 AM
Ignoring Unimportant
Left file: K:\HDA_FIN\user\JMan\All\A-0001.jpg     Right file: K:\HDA_FIN\user\JMan\All\B-0001.jpg
3454945 same pixel(s)
2154 ignored unimportant difference pixel(s)
2741 important difference pixel(s)

これは、スクリプトがフォルダー内の結合された jpeg を比較するときに何度も繰り返されます。しかし、一部の jpeg は 100% 同一であるため、重要でない、または重要な違いを無視することはありません。また、同じ違いと重要な違いがあるものもありますが、重要でないものはありません。したがって、「画像比較」で始まり、次の「画像比較」が始まる前に最後の「ピクセル」で終わる一致をキャプチャしようとしています。また。

私が試したこと

私がしていないのは醜い方法です: 私はストリーム リーダーを使用し、!EndOfStream 中に sr.ReadLine() を実行し、各行をリストに追加します。次に、for ループを使用してリストを反復処理し、一連の if ステートメントを適用して、ループ内の現在の文字列と次のいくつかの文字列が探しているものと一致するかどうかを判断し、一致する場合はそれらをオブジェクトにバインドします。しかし、確かに正規表現ははるかに単純です。

    var lineByLine = new List<string>();
    while (!sr.EndOfStream)
    {
        string line = sr.ReadLine();
        sb.AppendLine(line);
        if (line.Trim().Length > 0)  // && !line.Contains("picture-report layout"))
        {
            lineByLine.Add(line);
        }
    }

    Contents = sb.ToString();

    //get the report blocks


    for (int i = 0; i < lineByLine.Count; i++)
    {
        Block block;
        string[] lines = { "", "", "", "", "", "", "" };

        //does line contain pic compare? if so, this is the start of an object
        if (lineByLine[i].Contains("Picture Compare"))
        {
            lines[0] = lineByLine[i]; //start line
            block = new Block();
            lines[1] = lineByLine[i + 1]; //produces
            lines[2] = lineByLine[i + 2]; //subheading
            if (lineByLine[i + 3].Contains("Left"))
            {
                lines[3] = lineByLine[i + 3]; //file
                if (lineByLine[i + 4].Contains("same pixel(s)"))
                {
                    lines[4] = lineByLine[i + 4]; //same
                    if (lineByLine[i + 5].Contains("ignored unimportant"))
                    {
                        lines[5] = lineByLine[i + 5];
                        if (lineByLine[i + 6].Contains(" important difference"))
                        {
                            lines[6] = lineByLine[i + 6];
                        }
                    }
                }
                else if (lineByLine[i + 4].Contains("ignored unimportant"))
                {
                    lines[5] = lineByLine[i + 4];
                    if (lineByLine[i + 5].Contains(" important difference"))
                    {
                        lines[6] = lineByLine[i + 5];
                    }
                }
                else if (lineByLine[i + 4].Contains(" important difference"))
                {
                    lines[6] = lineByLine[i + 4];
                }
            }
            Blocks.Add(new Block(lines[0], lines[1], lines[2], lines[3], lines[4], lines[5], lines[6]));
        }
    }

}
finally
{
    sr.Close();
}

これは機能しますが、リファクタリングしてよりクリーンにしようとしています。私はこれを試しました:

 var matches = Regex.Matches(cr.Contents, "(Picture Compare)(.*?)(pixel)", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.ExplicitCapture);

-しかし、すべての場合で同じピクセルで停止します。もっと貪欲なものが必要です。何か案は?

4

2 に答える 2

2

終わりを見つける代わりに、次の始まりを見つけようとすることができます。

@"Picture Compare(?:(?!Picture Compare).)*"

Picture Compareこれは、新しい文字を開始しない限り、できるだけ多くの文字に一致しますPicture Compare(これが否定的な先読みの目的です)。これにより、これらすべてのブロックが得られるはずです。

次に、これらの各ブロックで、より簡単なスキャンを実行して、関心のある値を取得できます (残念ながら、どれがどれであるかはわかりません。そうでなければ、それらの別の正規表現もある可能性があります:P)。

于 2012-10-29T20:43:34.373 に答える
0

正規表現パターンを使用してみてください

Picture Compare\n?(?:(?!Picture Compare)[^\n]*\n?)*

Picture Compareそのため、行と次の行で始まらないすべての行を読みますPicture Compare

于 2012-10-29T20:51:31.707 に答える