我有以下字符串:
"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'),
...........
)
答案 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)
答案 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
将为空),以及一个没有引号的名称。