什么正则表达式应该用于3种可能的结局

时间:2012-10-29 20:32:34

标签: c# regex

这是一个令人头疼的问题。我有一段来自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()并将每行添加到List。然后我使用for循环遍历列表并应用一系列if语句来确定循环中的当前字符串和前面的几个字符串是否与我要查找的匹配,如果是,我将它们绑定到一个对象。但肯定的是Regex要简单得多。

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

- 但在所有情况下它都停在相同像素。我需要更贪婪的东西。有什么想法吗?

2 个答案:

答案 0 :(得分:2)

而不是找到结束,你可以尝试找到下一个开始:

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

这匹配Picture Compare,然后匹配尽可能多的字符,只要它们不启动新的Picture Compare(这就是负面预测的目的)。这应该只是给你所有这些块。

然后在每个块上,你可以做很多简单的扫描来获得你感兴趣的值(不幸的是,我不知道那些是哪些,否则我可能还有另一个正则表达式{{ 1}})。

答案 1 :(得分:0)

尝试使用正则表达式

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

所以你读了Picture Compare行以及所有不以Picture Compare

开头的行