C#正则表达式只找到多个可能结果中的一个

时间:2014-01-08 13:02:09

标签: c# regex string icalendar

我正在尝试使用C#中的.ics文件的内容。在我的第一步中,我想要做的是按事件分割文件的整个内容。我正试图用正则表达式实现这一点,我以前从未使用过。一个事件总是以“BEGIN:VEVENT”开头,以“END:VEVENT”结束。


我的代码:

    MatchCollection iCalMatches = Regex.Matches(iCal, @"BEGIN:VEVENT(.*)END:VEVENT");

    string testString = "";
    foreach (Match match in iCalMatches) {
        testString += match.Value + "<br/><br/>";
    }
    return testString;

“iCal”包含整个ics内容,没有任何换行符。


输入/输出:

所以文件内容看起来像这样:

  

开始:VEVENT

     

...

     

结束:VEVENT

     

BEGIN:VEVENT

     

...

     

END:VEVENT

但不是两个结果包含....

  

BEGIN:VEVENT

     

...

     

END:VEVENT

...我得到一个包含整个内容的结果。


PS:我知道有这样的库,但仍希望以这种方式工作。

3 个答案:

答案 0 :(得分:1)

您可以使用延迟匹配:

@"BEGIN:VEVENT(.*?)END:VEVENT"
                 ^

通过插入?,它会使.*匹配尽可能少(尽可能少),直到下一个END:VEVENT

答案 1 :(得分:1)

你需要使用延迟重复。默认情况下,如果您通过星形,花括号,加号等重复使用,正则表达式会尝试尽可能多地获得(贪婪)。如果您要激活延迟重复,请将(.*)替换为(.*?)

答案 2 :(得分:1)

正如其他答案所示,使用懒惰的比赛,你将能够得到你需要的东西。

或者,您可以编写一些简单的代码,将整个日历解析为字符串字典列表。

string[] lines = File.ReadAllLines("data.ics");
var events = new List<Dictionary<string, string>>();
int eventIndex = -1;
foreach (var line in lines)
{
    if (line == "BEGIN:VEVENT")
    {
        events.Add(new Dictionary<string,string>());
        eventIndex++;
    }
    else if (line != "END:VEVENT")
    {
        int positionOfColon = line.IndexOf(':');
        if (positionOfColon == -1) continue;
        string propertyName = line.Substring(0, positionOfColon - 1);
        string propertyValue = line.Substring(positionOfColon + 1);
        events[eventIndex].Add(propertyName, propertyValue);
    }
}

每个字典代表一个事件,每个条目都是ics文件中的一行。