2014-01-30 21 views
1

我想轉換一個搜索字符串/解析以下字符串:分手了的「字段名」 =「一些價值」

$search_term = ' "full name"="john smith" city="london" foo bar baz '; 

基本上搜索項任意數量的字段=值對,相隔空間。理想情況下,他們應該是一個陣列:

$array['full name'] = 'john smith'; 
$general = 'foo bar baz'; 

'foo bar baz'應該進入$ general變量。

我正在考慮在空格上切斷並避免使用正則表達式,但現在不太確定。

回答

2

怎麼樣這個新版本:

$str = ' foo "full name"="john smith" bar city="london" baz '; 

preg_match_all('/(?:"([^"]+)"="([^"]+)")|(?:([^= ]+)="([^"]+)")|([^"= ]+)/', $str, $m); 
$res = array(); 

for($i=0; $i < count($m[2]); $i++) { 
    if (empty($m[1][$i]) && empty($m[3][$i])) { 
     $res['general'] .= $m[5][$i]; 
    } elseif (!empty($m[1][$i])) { 
     $res[$m[1][$i]] = $m[2][$i]; 
    } else { 
     $res[$m[3][$i]] = $m[4][$i]; 
    } 
} 
print_r($res); 

輸出:

Array 
(
    [general] => foo bar baz 
    [full name] => john smith 
    [city] => london 
) 
+0

不幸的是,這不適用於像'foo「全名」=「john smith」bar city =「london」baz'(我的)那樣的字符串。不過,可能相應地調整正則表達式。 – akirk

+0

是的,順序會影響輸出,就像akirk說的那樣。 – trafalgar

+0

@akirk:是的,你說得對。 – Toto

1

雖然這不是一個特別優雅的解決方案,但它應該工作得很好。本質上,你首先替換引用的字符串,找到搜索條件,然後將其替換回來。

$search_term = ' "full name"="john smith" city="london" foo bar baz '; 

$replace = array(); 
// find all quoted strings 
preg_match_all('#"[^"]+"#', $search_term, $matches); 

// and replace them with something temporary 
foreach ($matches[0] as $k => $match) $replace[$match] = "quo" . $k . "ted"; 

$search_term_without_quotes = str_replace(array_keys($replace), array_values($replace), $search_term); 

$terms = explode(' ', $search_term_without_quotes); 

$array = array(); 
$general = ""; 
foreach ($terms as $term) { 
    // replace it back (notice the reversed array_values and array_keys 
    $term = str_replace(array_values($replace), array_keys($replace), $term); 
    // explode into two fields 
    // if an = can be in the first quoted term you need to move the replacing further down 
    $term = explode("=", $term, 2); 

    if (count($term) == 1) { 
     $general .= " " . trim($term[0], '"'); 
    } else { 
     $array[trim($term[0], '"')] = trim($term[1], '"'); 
    } 
} 
print_r($array); 
print_r($general); 

這給了你:

Array 
(
    [full name] => john smith 
    [city] => london 
) 
foo bar baz 
+0

哇,只是在30分鐘。謝謝。我會測試和調整它... – trafalgar

+0

你至少可以給我一個upvote;) – akirk

+0

感謝您的幫助 – trafalgar

0

試試這個:

function parse($str) { 
    function mytrim($str) { 
     return trim($str, '"'); 
    } 
    $rx = '/("[^"]*"|\S+)\=("[^"]*"|\S+)/s'; 
    $a_ret1 = preg_match_all($rx, $str, $arr)? 
     array_combine(array_map('mytrim', $arr[1]), array_map('mytrim', $arr[2])) : array(); 
    $str = preg_replace($rx, '', $str); 
    $a_ret2 = preg_match_all('/([^\s"]+)/s', $str, $arr)? $arr[1] : array(); 
    return array($a_ret1, $a_ret2); 
} 

$search_term = ' "full name"="john smith" city="london" foo bar baz '; 
list($a1, $a2) = parse($search_term); 
echo 'result 1: '. print_r($a1, true); 
echo 'result 2: '. print_r(implode(' ', $a2), true); 

Demo

相關問題