【问题标题】:Reading i-cal/ics attributes with line-breaks / line-folding使用换行符/换行符读取 i-cal/ics 属性
【发布时间】:2017-11-14 00:36:32
【问题描述】:

我想在 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 换行即可:

preg_replace("/\n /", "", $input_lines);

在 \n 之后有一个空格很重要。 之后,我可以继续正确地获取任何线路。

【问题讨论】:

  • 你必须使用 preg_match_all 吗?为什么不用preg_replace,匹配\n 并替换为空白phpliveregex.com/p/lY0
  • 仅供参考:这称为“线折叠”。可能会帮助您找到解决方案。
  • 啊,没想到。删除线折叠实际上是一个好主意,并且可以按我的意愿工作。我希望我能支持你的 cmets。谢谢。也许其他人会偶然发现这个问题,所以我会更新它。

标签: php regex icalendar


【解决方案1】:

由于您实际上并未匹配表达式,因此它作为 str_replace 而不是 preg_replace 会运行得更快。

$input_lines = str_replace("\n ", "", $input_lines);

我认为你也可以通过在 \n 上爆炸来加快其余的搜索速度,使用 strpos 查找第一个冒号,而不是使用 substr 获取它之前/之后的文本,但这是更多的函数调用,所以你可能想在一个大的 ical 文件上计时。如果文件很小,那么重写该部分的复杂性可能不值得。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 1970-01-01
    • 2013-02-27
    • 2019-06-16
    • 2010-09-16
    • 1970-01-01
    相关资源
    最近更新 更多