拆分搜索字符串“field names”=“some values”

时间:2014-01-30 12:11:50

标签: php regex

我想转换/解析以下字符串:

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

搜索词基本上是任意数量的field = value对,用空格分隔。理想情况下,它们应该是一个数组:

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

'foo bar baz'应该进入$ general变量。

我在想空间并避免使用正则表达式但现在不太确定。

3 个答案:

答案 0 :(得分: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
)

答案 1 :(得分: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 

答案 2 :(得分: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