我正致力于通过Google API将Google日历解析为DDay.iCal
的应用程序主要属性,属性易于处理 ... ev.Summary = evt.Title.Text;
问题是当我收到重复事件时,XML包含一个字段,如:
<gd:recurrence>
DTSTART;VALUE=DATE:20100916
DTEND;VALUE=DATE:20100917
RRULE:FREQ=YEARLY
</gd:recurrence>
或
<gd:recurrence>
DTSTART:20100915T220000Z
DTEND:20100916T220000Z
RRULE:FREQ=YEARLY;BYMONTH=9;WKST=SU"
</gd:recurrence>
使用以下代码:
String[] lines =
evt.Recurrence.Value.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
foreach (String line in lines)
{
if (line.StartsWith("R"))
{
RecurrencePattern rp = new RecurrencePattern(line);
ev.RecurrenceRules.Add(rp);
}
else
{
ISerializationContext ctx = new SerializationContext();
ISerializerFactory factory = new DDay.iCal.Serialization.iCalendar.SerializerFactory();
ICalendarProperty property = new CalendarProperty();
IStringSerializer serializer = factory.Build(property.GetType(), ctx) as IStringSerializer;
property = (ICalendarProperty)serializer.Deserialize(new StringReader(line));
ev.Properties.Add(property);
Console.Out.WriteLine(property.Name + " - " + property.Value);
}
}
RRULEs被正确解析,但问题是其他属性(日期时间)值是空的......
答案 0 :(得分:4)
这是我正在做的事情的起点,离开the RFC-5545 spec's recurrence rule。它没有完成规范,并且可能会因某些输入而中断,但它应该让你前进。我认为这应该都是可以使用RegEx做的,而像递归正确的解析器这样重的东西会有点过分。
RRULE:(?:FREQ=(DAILY|WEEKLY|SECONDLY|MINUTELY|HOURLY|DAILY|WEEKLY|MONTHLY|YEARLY);)?(?:COUNT=([0-9]+);)?(?:INTERVAL=([0-9]+);)?(?:BYDAY=([A-Z,]+);)?(?:UNTIL=([0-9]+);)?
我正在使用http://regexstorm.net/tester进行构建。
我使用的测试输入是:
DTSTART; TZID =美国/芝加哥:20140711T133000 \ nDTEND; TZID =美国/芝加哥:20140711T163000 \ nRRULE:FREQ = WEEKLY; INTERVAL = 8; BYDAY = FR; UNTIL = 20141101
DTSTART; TZID =美国/芝加哥:20140711T133000 \ nDTEND; TZID =美国/芝加哥:20140711T163000 \ nRRULE:FREQ = WEEKLY; COUNT = 5; INTERVAL = 8; BYDAY = FR; UNTIL = 20141101
DTSTART; TZID =美国/芝加哥:20140711T133000 \ nDTEND; TZID =美国/芝加哥:20140711T163000 \ nRRULE:FREQ = WEEKLY; BYDAY = FR; UNTIL = 20141101
样本匹配结果如下:
Index Position Matched String $1 $2 $3 $4 $5
0 90 RRULE:FREQ=WEEKLY;INTERVAL=8;BYDAY=FR;UNTIL=20141101 WEEKLY 8 FR 20141101
1 236 RRULE:FREQ=WEEKLY;COUNT=5;INTERVAL=8;BYDAY=FR;UNTIL=20141101 WEEKLY 5 8 FR 20141101
2 390 RRULE:FREQ=WEEKLY;BYDAY=FR;UNTIL=20141101 WEEKLY FR 20141101
用法如下:
string freqPattern = @"RRULE:(?:FREQ=(DAILY|WEEKLY|SECONDLY|MINUTELY|HOURLY|DAILY|WEEKLY|MONTHLY|YEARLY);?)?(?:COUNT=([0-9]+);?)?(?:INTERVAL=([0-9]+);?)?(?:BYDAY=([A-Z,]+);?)?(?:UNTIL=([0-9]+);?)?";
MatchCollection mc = Regex.Matches(rule, freqPattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase);
foreach (Match m in mc)
{
string frequency = m.Groups[1].ToString();
string count = m.Groups[2].ToString();
string interval = m.Groups[3].ToString();
string byday = m.Groups[4].ToString();
string until = m.Groups[5].ToString();
System.Console.WriteLine("recurrence => frequency: \"{0}\", count: \"{1}\", interval: \"{2}\", byday: \"{3}\", until: \"{4}\"", frequency, count, interval, byday, until);
}
答案 1 :(得分:-1)
这是何时使用正则表达式的一个很好的例子。试试这个进行一般解析:
\s*(\w+):((\w+=\w+;)+(\w+=\w+)?|\w+)
或者,您可能决定使用更具体模式的内容。
\s*(?:DTSTART:)(?'Start'\w+)
\s*(?:DTEND:)(?'End'\w+)
\s*(?:RRULE:)(?'Rule'(\w+=\w+;)+(\w+=\w+)?)