如何在PHP中或使用正则表达式拆分名称和电子邮件地址

时间:2009-10-27 16:47:39

标签: php regex

我有以下字符串:

"Test, User" < test@test.com >, "Another, Test" < another@test.com >, .........

我想要以下结果:

array(
  array('name' => 'Test, User', 'email' => 'test@test.com'),
  array('name' => 'Another, Test', 'email' => 'another@test.com'),  
  ...........
) 

5 个答案:

答案 0 :(得分:9)

preg_match_all()似乎合适:

$in = '"Test, User" < test@test.com >, "Another, Test" < another@test.com >, .........';
preg_match_all('!"(.*?)"\s+<\s*(.*?)\s*>!', $in, $matches);
$out = array();
for ($i=0; $i<count($matches[0]); $i++) {
  $out[] = array(
    'name' => $matches[1][$i],
    'email' => $matches[2][$i],
  );
}
print_r($out);

输出:

Array
(
    [0] => Array
        (
            [name] => Test, User
            [email] => test@test.com
        )

    [1] => Array
        (
            [name] => Another, Test
            [email] => another@test.com
        )

)

答案 1 :(得分:2)

我在这里将这个答案与另一个答案相结合,以创建一个相当完整的解析器:

function parseEmailListToArray($list) {
    $t = str_getcsv($list);

    foreach($t as $k => $v) {
        if (strpos($v,',') !== false) {
            $t[$k] = '"'.str_replace(' <','" <',$v);
        }
    }

    foreach ($t as $addr) {
        if (strpos($addr, '<')) {
            preg_match('!(.*?)\s?<\s*(.*?)\s*>!', $addr, $matches);
            $emails[] = array(
                'email' => $matches[2],
                'name' => $matches[1]
            );
        } else {
            $emails[] = array(
                'email' => $addr,
                'name' => ''
            );
        }
    }

    return $emails;
}

答案 2 :(得分:0)

为什么不通过模式匹配来preg_split

"Test, User" < test[at]test.com >,

然后preg_match找到名称和电子邮件组件,然后将它们放在一个数组中。

答案 3 :(得分:0)

$strs = preg_split($in,'".*" < .* >,');
foreach ($strs as $str){
$in1 = preg_match('/".+"/', $str);
$in2 = preg_match('/< .+ >/', $str);
push($out,array('name'=>$in1,'email'=>$in2);
}
echo $out;

答案 4 :(得分:0)

无法发表评论,但是根据cletus的回答,我将正则表达式扩展为:

$regex = '/(("([^"]*)"|[^",]*)\\s*<(.*?)>|[^",\\s]+)(?=(,|$))/';
preg_match_all($regex,$in,$matches,PREG_SET_ORDER);
$out = [];
foreach($matches as $match) $out[] = [
  'name' => $match[3] ?: trim($match[2]),
  'email' => trim($match[4]) ?: $match[1]
];

这也会匹配一个简单的foo@acme.com<bar@acme.com>name将为空),以及一个没有引号的名称。