我想在PHP中实现我非常基本的日历功能。但客户希望能够从其他来源导入自己的日历。我有一个通用的ics文件。 我发现有时大线,例如Long Descriptions或一些苹果iCal线会分解成一个新行,并以空格作为第一个字符。
我想通过preg_match_all使用正则表达式获取每个属性。
这是一个示例,其中包含来自Google和Apple属性的示例行以及我从客户处获得的类似说明。
BEGIN:VEVENT
DTSTART:20150123T060000Z
DTEND:20150123T070000Z
DTSTAMP:20171027T205827Z
UID:1234567894567890ß6543
CREATED:20150131T171526Z
ORGANIZER;CN=someemail@mail.com:mailto:email@server.com
UID:1234567890
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=NEEDS-ACTION;CN=So
me NameX-NUM-GUESTS=0:mailto:name@server.com
ATTENDEE;CUTYPE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;CN=Anoth
er Name;X-NUM-GUESTS=0:mailto:name@server.com
DESCRIPTION: this is a very long d\nescription. It brea
ks down if the l\nine is too long. It seems to be quit
e normal. But it \n also contains \n's.
X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-APPLE-MAPKIT-HANDLE=CAESmQIaEgnfNH1
2wAtJQBFuMT83NE0hQCKcAQoLRGV1dHNjaGxhbmQSAkRFGgZIZXNzZW4qEUZyYW5rZnVydCBhbS
BNYWluMhFGcmFua2Z1cnQgYW0gTWFpbjoFNjA1MjhCBFPDvGRSGUhlaW5yaWNoLUhvZmZtYW5uL
VN0cmHDn2VaAjEwYhxIZWlucmljaC1Ib2ZmbWFubi1TdHJhw59lIDEwigEJTmllZGVycmFkigEE
U8O8ZCocSGVpbnJpY2gtSG9mZm1hbm4tU3RyYcOfZSAxMDIcSGVpbnJpY2gtSG9mZm1hbm4tU3R
yYcOfZSAxMDIXNjA1MjggRnJhbmtmdXJ0IGFtIE1haW4yC0RldXRzY2hsYW5kODlAAA==;X-APP
LE-RADIUS=49.91306619367188;X-APPLE-REFERENCEFRAME=1;X-TITLE="A location , Frankfurt am Main, Germany":geo:12.345678,9.123456
LAST-MODIFIED:20150131T171526Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY: The Title
TRANSP:OPAQUE
END:VEVENT
我得到的正则表达式对于不会在下一行继续运行的行似乎工作正常:
/(((.*?:)(.*?)).*)/
的
BEGIN:VEVENT
DTSTART:20150123T060000Z
DTEND:20150123T070000Z
DTSTAMP:20171027T205827Z
UID:1234567894567890ß6543
CREATED:20150131T171526Z
UID:1234567890
DESCRIPTION: some description
LAST-MODIFIED:20150131T171526Z
LOCATION:
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY: The Title
TRANSP:OPAQUE
END:VEVENT
给出了这个:
array(5
0 => array(15
0 => BEGIN:VEVENT
1 => DTSTART:20150123T060000Z
2 => DTEND:20150123T070000Z
3 => DTSTAMP:20171027T205827Z
4 => UID:1234567894567890ß6543
5 => CREATED:20150131T171526Z
6 => UID:1234567890
7 => DESCRIPTION: some description
8 => LAST-MODIFIED:20150131T171526Z
9 => LOCATION:
10 => SEQUENCE:0
11 => STATUS:CONFIRMED
12 => SUMMARY: The Title
13 => TRANSP:OPAQUE
14 => END:VEVENT
)
http://www.phpliveregex.com/p/lXX(preg_match_all)
我肯定可以使用它,但我无法弄清楚如何检测可以包含任意数量换行符的属性中的换行符。 http://www.phpliveregex.com/p/lXY(preg_match_all)
就像我提供的确切示例一样,跟随正则表达式似乎有效:
(DESCRIPTION:(.*))|(X-APPLE(.*?)geo:(.*))|(((.*?:)(.*?)).*)|((.*)\n(.*):mailto:.*)|((.*):mailto:.*)
http://www.phpliveregex.com/p/lXW(preg_match_all)
但我不能涵盖任何一个案例,因为运行时可能会爆炸。
我没有从正确的角度看到这一点。 我只需要预先删除换行符:
preg_replace("/\n /", "", $input_lines);
在\ n后面有一个空格很重要。 在那之后,我可以继续正确地获得任何一条线。
答案 0 :(得分:0)
由于您实际上并未匹配表达式,因此它将作为str_replace而不是preg_replace运行得更快。
$input_lines = str_replace("\n ", "", $input_lines);
我认为你可以通过爆炸来加速搜索的其余部分,使用strpos查找第一个冒号而不是使用substr来获取它之前/之后的文本,但这是更多函数调用所以你可能想要在一个大型文件上计时。如果文件很小,重写该部分可能不值得复杂。