在PHP中解析字符串

时间:2014-02-12 13:58:24

标签: php regex parsing

我有一个ICS文件,当在谷歌日历,雅虎日历等创建会议时,我的服务器将上传该文件....我已经解析了日期,组织者等。来自ics文件。但我无法获得与会者名单。下面的代码将在ICS文件中。

BEGIN:VEVENT

ATTENDEE;RSVP=TRUE:mailto:xxxxxxx

  xx@xxx.com
ATTENDEE;RSVP=TRUE:mailto:yyy@yyy.com

ATTENDEE;RSVP=TRUE:mailto:zzz@zzz.com

ATTENDEE;RSVP=TRUE:mailto:aaa@aaa.com

CLASS:PUBLIC

从上面的代码中,我需要与mailto参数关联的电子邮件ID。请帮助我实现这一目标。

<?php
$cal = file_get_contents("ics_files/outlook.ics");
$cal = str_replace("\n", "", $cal);
preg_match_all('/mailto:(.*?)ATTENDEE/', $cal, $attendees);
?>

4 个答案:

答案 0 :(得分:1)

如果删除从ics数据中删除换行符(\n)的预格式化行,则可以使用简单的正则表达式:

/mailto:(.*?)(?:ATTENDEE;|CLASS:)/s

/s告诉正则表达式引擎将换行符与.匹配。如果您想放弃/s,则可以使用:

/mailto:((?:\r\n|\n|.)*?)(?:ATTENDEE;|CLASS:)/

使用PHP的preg_match_all()

preg_match_all('/mailto:(.*?)(?:ATTENDEE;|CLASS:)/s', $cal, $attendees);

输出:

print_r($attendees[1]);

Array (
    [0] => xxxxxxx

  xx@xxx.com
    [1] => yyy@yyy.com
    [2] => zzz@zzz.com
    [3] => aaa@aaa.com
)

然后,您可以遍历$attendees[1]数组并应用您希望的任何电子邮件地址逻辑/格式。

示例:

foreach ($attendees[1] as $attendee) {
    // remove any extra spaces/newlines from the address
    $attendee = trim(preg_replace('/\s\s+/', ' ', str_replace("\n", ' ', $attendee)));

    // split the address into any available name/email-address combination
    $address = explode(' ', $attendee);

    echo $address[0];
    if (!empty($address[1])) {
        // there is a name/email-address combination available
        echo ' <' . $address[1] . '>';
    }
    echo "\n";
}

输出:

xxxxxxx <xx@xxx.com>
yyy@yyy.com
zzz@zzz.com
aaa@aaa.com

答案 1 :(得分:0)

您正在从文件中删除所有换行符,从而将所有内容都放在一行中。由于.*?匹配任何不是换行符(非贪婪匹配)的字符,因此您也会收到包含空格的电子邮件 - 例如,xxxxxxx xx@example.com将匹配。

您可以更具体一点,并将正则表达式限制为仅匹配(并捕获)mailto:后跟任何不是空格的内容,后跟任何空格字符(可以是制表符,换行符,或者不同的空间特征):

preg_match_all('/mailto:(\S+)\s/', $cal, $attendees);
print_r($attendees[1]);

这将返回以下数组:

Array
(
    [0] => xxxxxxx     /* <--- not valid */
    [1] => yyy@yyy.com
    [2] => zzz@zzz.com
    [3] => aaa@aaa.com
)

但是,这些都不是有效的电子邮件地址。如果您还要验证这些电子邮件地址并过滤掉那些无效的电子邮件地址,您可以使用array_filter() filter_var验证作为回调 - 它比使用正则表达式来完成任务更容易。

if ($match) {
    $valid_emails = array_filter($attendees[1], function ($email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL);
    });
}

print_r($valid_emails);

输出:

Array
(
    [1] => yyy@yyy.com
    [2] => zzz@zzz.com
    [3] => aaa@aaa.com
)

答案 2 :(得分:0)

试试这个正则表达式,

/ATTENDEE.*mailto:(\S+)/g

它只会将所有与会者的邮件与

匹配

答案 3 :(得分:-1)

试试这个

preg_match_all('/mailto:(.+)/', $str, $matches);
echo "<pre>";
print_r($matches[1]);